eberhenriquez94 commited on
Commit
200fce2
·
verified ·
1 Parent(s): be7f71b
Files changed (1) hide show
  1. app.py +50 -94
app.py CHANGED
@@ -1,167 +1,123 @@
1
  import os
2
  import asyncio
3
- import requests # Necesario para interactuar con la API de Fireworks
4
  import gradio as gr
5
 
6
- # --- CONFIGURACIÓN DE LA API DE FIREWORKS AI ---
7
- # 1. Obtener la Clave API de Fireworks de forma segura desde los Secrets del Space
8
- FIREWORKS_API_KEY = os.getenv("FIREWORKS_API_KEY")
9
- if not FIREWORKS_API_KEY:
10
- print("ADVERTENCIA: La variable de entorno FIREWORKS_API_KEY no está configurada en los Secrets del Space.")
11
- # Descomenta la siguiente línea si quieres que la app falle si no hay clave:
12
- # raise ValueError("La clave FIREWORKS_API_KEY no está configurada en los Secrets del Space.")
 
 
 
 
 
 
13
 
14
- # 2. Definir el endpoint y el modelo a utilizar
15
- FIREWORKS_API_URL = "https://api.fireworks.ai/inference/v1/chat/completions"
16
- FIREWORKS_MODEL_NAME = "accounts/fireworks/models/qwen3-235b-a22b-thinking-2507"
17
 
18
  # --- DIRECTIVA DE INSTRUCCIÓN (Rol del Agente) ---
19
  instruction = """
20
- Actúa como un Ministro experto de la Excelentísima Corte Suprema de Chile, con profunda especialización en Derecho de Familia y dominio absoluto de las Leyes N° 19.968 y N° 14.908, la jurisprudencia relevante y los principios rectores (interés superior del niño/a/adolescente, corresponsabilidad, etc.).
21
- Tu tarea es perfeccionar exclusivamente la **forma** (redacción, estilo, sintaxis, gramática) de un borrador de resolución judicial en materia de familia que se te proporcionará, sin alterar su contenido sustantivo. El objetivo es que el texto final refleje la máxima claridad expositiva, precisión jurídica y formalidad protocolar, emulando los más altos estándares de las resoluciones de la Corte Suprema.
22
- **PRINCIPIO FUNDAMENTAL:** Tu intervención se limita estrictamente a la **forma** del documento. El **fondo** (contenido sustantivo) es intocable.
23
- **RESTRICCIONES INALTERABLES:**
24
- 1. **Estructura Intacta:** NO modifiques la estructura del documento (secciones como VISTOS, CONSIDERANDOS, RESUELVO; numeración; orden de párrafos; títulos). Esta restricción es absoluta.
25
- 2. **Hechos Inmodificables:** NO alteres los hechos establecidos como probados (fechas, nombres, RUTs, descripciones, citas).
26
- 3. **Razonamiento Jurídico Intocable:** NO modifiques, complementes ni suprimas la argumentación legal, la interpretación normativa o las conclusiones jurídicas del borrador original.
27
- 4. **Sin Añadidos:** NO agregues información nueva de ningún tipo (incluida jurisprudencia no presente en el original). Trabaja únicamente con el texto proporcionado.
28
- **GUÍA DE ESTILO IMPERATIVA (Estilo Corte Suprema):**
29
- * **Formalidad Extrema:** Lenguaje rigurosamente formal, institucional y protocolar. Absolutamente impersonal (tercera persona o plural mayestático). Cero coloquialismos o subjetividad.
30
- * **Precisión Técnica:** Utiliza terminología jurídica específica e inequívoca del Derecho de Familia chileno y las leyes mencionadas.
31
- * **Tono y Sintaxis:** Tono autoritario, neutral y solemne. Sintaxis elaborada, precisa, con uso adecuado de conectores lógicos ("Atendido que", "Teniendo presente que", "En consecuencia") y construcciones propias del lenguaje judicial chileno.
32
- * **Fórmulas y Términos Jurídicos:** Emplea con naturalidad y pertinencia, donde el contexto lo requiera para mayor precisión y autenticidad, fórmulas protocolares ("Notifíquese por el estado diario", "Téngase presente", "A lo principal") y términos jurídicos específicos como "A sus antecedentes", "Ha lugar" / "No ha lugar", "Estese a lo resuelto", "Previo a proveer", "En mérito de autos", "Solicítese lo que en derecho corresponda", "Venga en forma", entre otros relevantes.
33
- * **Verbos Imperativos:** Usa el modo imperativo formal para decisiones y órdenes ("Notifíquese", "Cítese", "Regístrese", "Archívese", "Ofíciese", "Cúmplase").
34
- **FORMATO DE SALIDA:**
35
  Proporciona únicamente el texto completo del borrador de la resolución judicial, revisado y perfeccionado según todas las instrucciones anteriores. No incluyas comentarios, explicaciones ni encabezados adicionales.
36
  """
37
 
38
- # --- FUNCIÓN PARA LLAMAR A LA API DE FIREWORKS AI ---
39
- async def call_fireworks_api(user_prompt: str, system_instruction: str) -> str:
40
  """
41
- Realiza una solicitud a la API de Fireworks AI para generar contenido.
42
  """
43
- if not FIREWORKS_API_KEY:
44
- return "Error: La clave API de Fireworks no está configurada. Por favor, añádela a los 'Secrets' de este Space."
45
 
46
  headers = {
47
- "Accept": "application/json",
48
- "Content-Type": "application/json",
49
- "Authorization": f"Bearer {FIREWORKS_API_KEY}"
50
  }
51
 
52
  payload = {
53
- "model": FIREWORKS_MODEL_NAME,
54
  "temperature": 0.2,
55
  "top_p": 0.7,
56
  "max_tokens": 8192,
 
 
57
  "messages": [
58
  {"role": "system", "content": system_instruction},
59
  {"role": "user", "content": user_prompt}
60
- ]
61
  }
62
 
63
  try:
 
64
  loop = asyncio.get_event_loop()
65
- response = await loop.run_in_executor(
66
- None,
67
- lambda: requests.post(FIREWORKS_API_URL, json=payload, headers=headers, timeout=60)
68
- )
69
  response.raise_for_status()
70
  data = response.json()
71
 
72
  if data and 'choices' in data and len(data['choices']) > 0 and 'message' in data['choices'][0] and 'content' in data['choices'][0]['message']:
73
  return data['choices'][0]['message']['content']
74
  else:
75
- return f"Error: Formato de respuesta inesperado de la API de Fireworks. Respuesta: {str(data)[:500]}"
76
 
77
  except requests.exceptions.HTTPError as errh:
78
- return f"Error HTTP de la API de Fireworks: {errh}\nDetalle: {str(response.text)[:500]}"
79
  except requests.exceptions.ConnectionError as errc:
80
- return f"Error de conexión con la API de Fireworks: {errc}"
81
  except requests.exceptions.Timeout as errt:
82
- return f"Tiempo de espera agotado con la API de Fireworks: {errt}"
83
  except requests.exceptions.RequestException as err:
84
- return f"Error al realizar la solicitud a la API de Fireworks: {err}"
85
  except Exception as e:
86
  return f"Error inesperado durante la llamada a la API: {e}"
87
 
88
  # --- FUNCIÓN PRINCIPAL DE PREDICCIÓN PARA GRADIO ---
89
  async def predict(borrador: str) -> str:
90
  """
91
- Función que recibe el borrador judicial y lo envía a la API de Fireworks para su perfeccionamiento.
92
  """
93
  if not borrador.strip():
94
  return "Por favor, introduce un borrador judicial para perfeccionar."
95
- if not FIREWORKS_API_KEY:
96
- return "Error: La clave API de Fireworks no está configurada en los Secrets del Space. No se puede procesar la solicitud."
97
 
98
- improved_text = await call_fireworks_api(borrador, instruction)
99
  return improved_text
100
 
101
  # --- INTERFAZ DE GRADIO ---
102
- with gr.Blocks(theme=gr.themes.Soft()) as demo:
103
  gr.Markdown(
104
  """
105
  # ⚖️ Perfeccionador de Resoluciones Judiciales (Chile) ⚖️
106
  **Estilo Excelentísima Corte Suprema**
107
- Esta herramienta utiliza el modelo `Qwen/Qwen3-235B-A22B-Thinking-2507` a través de Fireworks AI para refinar la forma de borradores de resoluciones judiciales en materia de familia.
 
108
  **Importante:** El contenido sustantivo (hechos, razonamiento, decisión) del borrador original **no será alterado**. La IA se enfoca exclusivamente en el lenguaje, la sintaxis y la formalidad protocolar.
109
  """
110
  )
111
-
112
- with gr.Row():
113
- with gr.Column(scale=2):
114
- borrador_input = gr.Textbox(
115
- label="📄 Borrador judicial (texto a perfeccionar)",
116
- placeholder="Pega aquí el borrador de la resolución judicial...",
117
  lines=20,
118
  interactive=True
119
  )
120
- with gr.Column(scale=3):
121
  output_text = gr.Textbox(
122
  label="✨ Resultado perfeccionado (estilo Corte Suprema)",
123
  placeholder="El texto corregido por el modelo aparecerá aquí...",
124
- lines=20,
125
- interactive=False,
126
- show_copy_button=True
127
- )
128
-
129
- submit_btn = gr.Button("Perfeccionar Borrador", variant="primary")
130
-
131
- gr.Examples(
132
- examples=[
133
- [
134
- """VISTOS:
135
- Se presenta demanda de alimentos menores por Juan Perez contra Maria Soto. El demandante alega que no puede trabajar. La demandada dice que sí puede.
136
- CONSIDERANDOS:
137
- 1. Que el niño necesita plata.
138
- 2. Que el papa tiene que pagar.
139
- RESUELVO:
140
- Pague $100.000. Notifiquese."""
141
- ],
142
- [
143
- """SENTENCIA:
144
- Causa RIT F-123-2023.
145
- En Santiago, a cinco de enero de dos mil veinticuatro.
146
- VISTOS:
147
- Que doña CARLA ANDREA MUÑOZ SOTO, RUT Nº 15.XXX.XXX-X, interpuso demanda de divorcio unilateral por cese de convivencia en contra de don PEDRO ANTONIO PAVEZ LILLO, RUT Nº 14.XXX.XXX-X. Funda su acción en que contrajeron matrimonio el 10 de marzo de 2010, y que el cese de convivencia se produjo en julio de 2018, sin que se haya reanudado la vida en común.
148
- CONSIDERANDO:
149
- PRIMERO: Que la parte demandante acompañó certificado de matrimonio y acta de cese de convivencia.
150
- SEGUNDO: Que el demandado no contestó la demanda.
151
- TERCERO: Que se cumplen los requisitos del art. 55 de la Ley de Matrimonio Civil.
152
- POR TANTO, SE DECLARA:
153
- Que se acoge la demanda y se declara el divorcio.
154
- Ofíciese al Registro Civil.
155
- Cúmplase."""
156
- ],
157
  ],
158
  inputs=borrador_input,
159
  outputs=output_text,
160
- fn=predict,
161
- cache_examples=False,
162
  )
163
 
164
- submit_btn.click(fn=predict, inputs=borrador_input, outputs=output_text, api_name="predict_sync")
165
 
166
  # --- LANZAR LA INTERFAZ DE GRADIO ---
 
 
 
 
167
  demo.launch()
 
1
  import os
2
  import asyncio
3
+ import requests # Necesario para interactuar con la API de NVIDIA
4
  import gradio as gr
5
 
6
+ # --- CONFIGURACIÓN DE LA API DE NVIDIA ---
7
+ # 1. Obtener la Clave API de NVIDIA de forma segura desde los Secrets del Space
8
+ NVIDIA_API_KEY = os.getenv("NVIDIA_API_KEY")
9
+ if not NVIDIA_API_KEY:
10
+ # En un Space, si la clave no está configurada, la app puede fallar al inicio
11
+ # o puedes manejarlo mostrando un mensaje de error en la UI.
12
+ # Aquí, simplemente imprimiremos un aviso y la función de API fallará.
13
+ print("ADVERTENCIA: La variable de entorno NVIDIA_API_KEY no está configurada en los Secrets del Space.")
14
+ # Podrías lanzar un error aquí si prefieres que la app no inicie sin la clave:
15
+ # raise ValueError("La clave NVIDIA_API_KEY no está configurada en los Secrets del Space.")
16
+
17
+ NVIDIA_API_URL = "https://integrate.api.nvidia.com/v1/chat/completions"
18
+ NVIDIA_MODEL_NAME = "qwen/qwen3-235b-a22b" # El modelo que especificaste
19
 
 
 
 
20
 
21
  # --- DIRECTIVA DE INSTRUCCIÓN (Rol del Agente) ---
22
  instruction = """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  Proporciona únicamente el texto completo del borrador de la resolución judicial, revisado y perfeccionado según todas las instrucciones anteriores. No incluyas comentarios, explicaciones ni encabezados adicionales.
24
  """
25
 
26
+ # --- FUNCIÓN PARA LLAMAR A LA API DE NVIDIA ---
27
+ async def call_nvidia_api(user_prompt: str, system_instruction: str) -> str:
28
  """
29
+ Realiza una solicitud a la API de NVIDIA para generar contenido.
30
  """
31
+ if not NVIDIA_API_KEY:
32
+ return "Error: La clave API de NVIDIA no está configurada. Por favor, añádela a los 'Secrets' de este Space."
33
 
34
  headers = {
35
+ "accept": "application/json",
36
+ "content-type": "application/json",
37
+ "Authorization": f"Bearer {NVIDIA_API_KEY}"
38
  }
39
 
40
  payload = {
41
+ "model": NVIDIA_MODEL_NAME,
42
  "temperature": 0.2,
43
  "top_p": 0.7,
44
  "max_tokens": 8192,
45
+ "seed": None,
46
+ "stream": False,
47
  "messages": [
48
  {"role": "system", "content": system_instruction},
49
  {"role": "user", "content": user_prompt}
 
50
  }
51
 
52
  try:
53
+ # Ejecuta la solicitud síncrona en un hilo separado para no bloquear asyncio
54
  loop = asyncio.get_event_loop()
55
+ response = await loop.run_in_executor(None, lambda: requests.post(NVIDIA_API_URL, json=payload, headers=headers, timeout=60)) # Añadido timeout
56
+
57
+
58
+
59
  response.raise_for_status()
60
  data = response.json()
61
 
62
  if data and 'choices' in data and len(data['choices']) > 0 and 'message' in data['choices'][0] and 'content' in data['choices'][0]['message']:
63
  return data['choices'][0]['message']['content']
64
  else:
65
+ return f"Error: Formato de respuesta inesperado de la API de NVIDIA. Respuesta: {str(data)[:500]}" # Limita la longitud del error
66
 
67
  except requests.exceptions.HTTPError as errh:
68
+ return f"Error HTTP de la API de NVIDIA: {errh}\nDetalle: {str(response.text)[:500]}"
69
  except requests.exceptions.ConnectionError as errc:
70
+ return f"Error de conexión con la API de NVIDIA: {errc}"
71
  except requests.exceptions.Timeout as errt:
72
+ return f"Tiempo de espera agotado con la API de NVIDIA: {errt}"
73
  except requests.exceptions.RequestException as err:
74
+ return f"Error al realizar la solicitud a la API de NVIDIA: {err}"
75
  except Exception as e:
76
  return f"Error inesperado durante la llamada a la API: {e}"
77
 
78
  # --- FUNCIÓN PRINCIPAL DE PREDICCIÓN PARA GRADIO ---
79
  async def predict(borrador: str) -> str:
80
  """
81
+ Función que recibe el borrador judicial y lo envía a la API de NVIDIA para su perfeccionamiento.
82
  """
83
  if not borrador.strip():
84
  return "Por favor, introduce un borrador judicial para perfeccionar."
85
+ if not NVIDIA_API_KEY: # Comprobación adicional antes de llamar a la API
86
+ return "Error: La clave API de NVIDIA no está configurada en los Secrets del Space. No se puede procesar la solicitud."
87
 
88
+ improved_text = await call_nvidia_api(borrador, instruction)
89
  return improved_text
90
 
91
  # --- INTERFAZ DE GRADIO ---
92
+ with gr.Blocks(theme=gr.themes.Soft()) as demo: # Puedes probar diferentes temas de Gradio
93
  gr.Markdown(
94
  """
95
  # ⚖️ Perfeccionador de Resoluciones Judiciales (Chile) ⚖️
96
  **Estilo Excelentísima Corte Suprema**
97
+
98
+ Esta herramienta utiliza el modelo `qwen/qwen3-235b-a22b` de NVIDIA para refinar la forma de borradores de resoluciones judiciales en materia de familia.
99
  **Importante:** El contenido sustantivo (hechos, razonamiento, decisión) del borrador original **no será alterado**. La IA se enfoca exclusivamente en el lenguaje, la sintaxis y la formalidad protocolar.
100
  """
101
  )
 
 
 
 
 
 
102
  lines=20,
103
  interactive=True
104
  )
105
+ with gr.Column(scale=3): # Damos más espacio a la salida
106
  output_text = gr.Textbox(
107
  label="✨ Resultado perfeccionado (estilo Corte Suprema)",
108
  placeholder="El texto corregido por el modelo aparecerá aquí...",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
109
  ],
110
  inputs=borrador_input,
111
  outputs=output_text,
112
+ fn=predict, # La función que se llamará con los ejemplos
113
+ cache_examples=False, # Desactiva el cache si los resultados pueden variar o para asegurar la última versión del prompt
114
  )
115
 
116
+ submit_btn.click(fn=predict, inputs=borrador_input, outputs=output_text, api_name="predict_sync") # api_name opcional
117
 
118
  # --- LANZAR LA INTERFAZ DE GRADIO ---
119
+ # Cuando se ejecuta en Hugging Face Spaces, no necesitas if __name__ == "__main__":
120
+ # Gradio lo maneja automáticamente.
121
+ # demo.launch() sin argumentos es suficiente para Spaces.
122
+ # Si quisieras habilitar la cola para manejar múltiples usuarios: demo.launch(enable_queue=True)
123
  demo.launch()