eberhenriquez94 commited on
Commit
554f4ad
·
verified ·
1 Parent(s): 957cd50
Files changed (1) hide show
  1. app.py +148 -60
app.py CHANGED
@@ -1,86 +1,174 @@
1
  import os
2
  import asyncio
3
- from google import genai
4
- from google.genai import types
5
  import gradio as gr
6
 
7
- # Configuración de la clave de API
8
- GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
9
- if not GEMINI_API_KEY:
10
- raise ValueError("La clave GEMINI_API_KEY no está configurada correctamente.")
11
-
12
- # Cliente Gemini
13
- client = genai.Client(api_key=GEMINI_API_KEY)
14
-
 
 
 
 
 
 
 
15
  instruction = """
16
  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.).
17
-
18
  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.
19
-
20
  **PRINCIPIO FUNDAMENTAL:** Tu intervención se limita estrictamente a la **forma** del documento. El **fondo** (contenido sustantivo) es intocable.
21
-
22
  **RESTRICCIONES INALTERABLES:**
23
-
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
-
29
  **GUÍA DE ESTILO IMPERATIVA (Estilo Corte Suprema):**
30
-
31
  * **Formalidad Extrema:** Lenguaje rigurosamente formal, institucional y protocolar. Absolutamente impersonal (tercera persona o plural mayestático). Cero coloquialismos o subjetividad.
32
  * **Precisión Técnica:** Utiliza terminología jurídica específica e inequívoca del Derecho de Familia chileno y las leyes mencionadas.
33
  * **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.
34
  * **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.
35
  * **Verbos Imperativos:** Usa el modo imperativo formal para decisiones y órdenes ("Notifíquese", "Cítese", "Regístrese", "Archívese", "Ofíciese", "Cúmplase").
36
-
37
  **FORMATO DE SALIDA:**
38
-
39
  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.
40
  """
41
 
42
- # Configuración de generación
43
- generation_config = types.GenerateContentConfig(
44
- system_instruction=instruction,
45
- temperature=0.5,
46
- max_output_tokens=65536,
47
- )
48
-
49
- # Modelos
50
- model_flash_exp = "gemini-2.0-flash"
51
- model_gemini_ex = "gemini-1.5-pro"
52
-
53
- # Genera contenido con un modelo específico
54
- async def generate_content_async(model_name, borrador):
55
- response = await client.aio.models.generate_content(
56
- model=model_name,
57
- contents=borrador,
58
- config=generation_config,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  )
60
- return response.text
61
-
62
- # Ejecuta ambos modelos y combina sus respuestas
63
- async def predict(borrador):
64
- flash_task = asyncio.create_task(generate_content_async(model_flash_exp, borrador))
65
- gemini_task = asyncio.create_task(generate_content_async(model_gemini_ex, borrador))
66
- flash_result, gemini_result = await asyncio.gather(flash_task, gemini_task)
67
- return f"{flash_result}\n\n{gemini_result}"
68
-
69
- # Interfaz de Gradio
70
- with gr.Blocks() as demo:
71
- gr.Markdown("### Mejorador de resoluciones judiciales - Derecho de Familia en Chile")
72
- borrador_input = gr.Textbox(
73
- label="Borrador judicial",
74
- placeholder="Escribe o pega el texto aquí...",
75
- lines=10
76
- )
77
- output = gr.Textbox(
78
- label="Resultado mejorado",
79
- placeholder="El resultado aparecerá aquí...",
80
- lines=15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  )
82
- submit_btn = gr.Button("Enviar")
83
- submit_btn.click(fn=predict, inputs=borrador_input, outputs=output, api_name="predict_sync")
84
 
85
- if __name__ == "__main__":
86
- 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
+ # --- DIRECTIVA DE INSTRUCCIÓN (Rol del Agente) ---
21
  instruction = """
22
  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.).
 
23
  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.
 
24
  **PRINCIPIO FUNDAMENTAL:** Tu intervención se limita estrictamente a la **forma** del documento. El **fondo** (contenido sustantivo) es intocable.
 
25
  **RESTRICCIONES INALTERABLES:**
 
26
  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.
27
  2. **Hechos Inmodificables:** NO alteres los hechos establecidos como probados (fechas, nombres, RUTs, descripciones, citas).
28
  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.
29
  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.
 
30
  **GUÍA DE ESTILO IMPERATIVA (Estilo Corte Suprema):**
 
31
  * **Formalidad Extrema:** Lenguaje rigurosamente formal, institucional y protocolar. Absolutamente impersonal (tercera persona o plural mayestático). Cero coloquialismos o subjetividad.
32
  * **Precisión Técnica:** Utiliza terminología jurídica específica e inequívoca del Derecho de Familia chileno y las leyes mencionadas.
33
  * **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.
34
  * **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.
35
  * **Verbos Imperativos:** Usa el modo imperativo formal para decisiones y órdenes ("Notifíquese", "Cítese", "Regístrese", "Archívese", "Ofíciese", "Cúmplase").
 
36
  **FORMATO DE SALIDA:**
 
37
  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.
38
  """
39
 
40
+ # --- FUNCIÓN PARA LLAMAR A LA API DE NVIDIA ---
41
+ async def call_nvidia_api(user_prompt: str, system_instruction: str) -> str:
42
+ """
43
+ Realiza una solicitud a la API de NVIDIA para generar contenido.
44
+ """
45
+ if not NVIDIA_API_KEY:
46
+ return "Error: La clave API de NVIDIA no está configurada. Por favor, añádela a los 'Secrets' de este Space."
47
+
48
+ headers = {
49
+ "accept": "application/json",
50
+ "content-type": "application/json",
51
+ "Authorization": f"Bearer {NVIDIA_API_KEY}"
52
+ }
53
+
54
+ payload = {
55
+ "model": NVIDIA_MODEL_NAME,
56
+ "temperature": 0.2,
57
+ "top_p": 0.7,
58
+ "max_tokens": 8192,
59
+ "seed": None,
60
+ "stream": False,
61
+ "messages": [
62
+ {"role": "system", "content": system_instruction},
63
+ {"role": "user", "content": user_prompt}
64
+ ]
65
+ }
66
+
67
+ try:
68
+ # Ejecuta la solicitud síncrona en un hilo separado para no bloquear asyncio
69
+ loop = asyncio.get_event_loop()
70
+ response = await loop.run_in_executor(None, lambda: requests.post(NVIDIA_API_URL, json=payload, headers=headers, timeout=60)) # Añadido timeout
71
+ response.raise_for_status()
72
+ data = response.json()
73
+
74
+ if data and 'choices' in data and len(data['choices']) > 0 and 'message' in data['choices'][0] and 'content' in data['choices'][0]['message']:
75
+ return data['choices'][0]['message']['content']
76
+ else:
77
+ return f"Error: Formato de respuesta inesperado de la API de NVIDIA. Respuesta: {str(data)[:500]}" # Limita la longitud del error
78
+
79
+ except requests.exceptions.HTTPError as errh:
80
+ return f"Error HTTP de la API de NVIDIA: {errh}\nDetalle: {str(response.text)[:500]}"
81
+ except requests.exceptions.ConnectionError as errc:
82
+ return f"Error de conexión con la API de NVIDIA: {errc}"
83
+ except requests.exceptions.Timeout as errt:
84
+ return f"Tiempo de espera agotado con la API de NVIDIA: {errt}"
85
+ except requests.exceptions.RequestException as err:
86
+ return f"Error al realizar la solicitud a la API de NVIDIA: {err}"
87
+ except Exception as e:
88
+ return f"Error inesperado durante la llamada a la API: {e}"
89
+
90
+ # --- FUNCIÓN PRINCIPAL DE PREDICCIÓN PARA GRADIO ---
91
+ async def predict(borrador: str) -> str:
92
+ """
93
+ Función que recibe el borrador judicial y lo envía a la API de NVIDIA para su perfeccionamiento.
94
+ """
95
+ if not borrador.strip():
96
+ return "Por favor, introduce un borrador judicial para perfeccionar."
97
+ if not NVIDIA_API_KEY: # Comprobación adicional antes de llamar a la API
98
+ return "Error: La clave API de NVIDIA no está configurada en los Secrets del Space. No se puede procesar la solicitud."
99
+
100
+ improved_text = await call_nvidia_api(borrador, instruction)
101
+ return improved_text
102
+
103
+ # --- INTERFAZ DE GRADIO ---
104
+ with gr.Blocks(theme=gr.themes.Soft()) as demo: # Puedes probar diferentes temas de Gradio
105
+ gr.Markdown(
106
+ """
107
+ # ⚖️ Perfeccionador de Resoluciones Judiciales (Chile) ⚖️
108
+ **Estilo Excelentísima Corte Suprema**
109
+
110
+ Esta herramienta utiliza el modelo `qwen/qwen3-235b-a22b` de NVIDIA para refinar la forma de borradores de resoluciones judiciales en materia de familia.
111
+ **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.
112
+ """
113
  )
114
+
115
+ with gr.Row():
116
+ with gr.Column(scale=2):
117
+ borrador_input = gr.Textbox(
118
+ label="📄 Borrador judicial (texto a perfeccionar)",
119
+ placeholder="Pega aquí el borrador de la resolución judicial...",
120
+ lines=20,
121
+ interactive=True
122
+ )
123
+ with gr.Column(scale=3): # Damos más espacio a la salida
124
+ output_text = gr.Textbox(
125
+ label=" Resultado perfeccionado (estilo Corte Suprema)",
126
+ placeholder="El texto corregido por el modelo aparecerá aquí...",
127
+ lines=20,
128
+ interactive=False,
129
+ show_copy_button=True
130
+ )
131
+
132
+ submit_btn = gr.Button("Perfeccionar Borrador", variant="primary")
133
+
134
+ gr.Examples(
135
+ examples=[
136
+ [
137
+ """VISTOS:
138
+ 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.
139
+ CONSIDERANDOS:
140
+ 1. Que el niño necesita plata.
141
+ 2. Que el papa tiene que pagar.
142
+ RESUELVO:
143
+ Pague $100.000. Notifiquese."""
144
+ ],
145
+ [
146
+ """SENTENCIA:
147
+ Causa RIT F-123-2023.
148
+ En Santiago, a cinco de enero de dos mil veinticuatro.
149
+ VISTOS:
150
+ 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.
151
+ CONSIDERANDO:
152
+ PRIMERO: Que la parte demandante acompañó certificado de matrimonio y acta de cese de convivencia.
153
+ SEGUNDO: Que el demandado no contestó la demanda.
154
+ TERCERO: Que se cumplen los requisitos del art. 55 de la Ley de Matrimonio Civil.
155
+ POR TANTO, SE DECLARA:
156
+ Que se acoge la demanda y se declara el divorcio.
157
+ Ofíciese al Registro Civil.
158
+ Cúmplase."""
159
+ ],
160
+ ],
161
+ inputs=borrador_input,
162
+ outputs=output_text,
163
+ fn=predict, # La función que se llamará con los ejemplos
164
+ cache_examples=False, # Desactiva el cache si los resultados pueden variar o para asegurar la última versión del prompt
165
  )
 
 
166
 
167
+ submit_btn.click(fn=predict, inputs=borrador_input, outputs=output_text, api_name="predict_sync") # api_name opcional
168
+
169
+ # --- LANZAR LA INTERFAZ DE GRADIO ---
170
+ # Cuando se ejecuta en Hugging Face Spaces, no necesitas if __name__ == "__main__":
171
+ # Gradio lo maneja automáticamente.
172
+ # demo.launch() sin argumentos es suficiente para Spaces.
173
+ # Si quisieras habilitar la cola para manejar múltiples usuarios: demo.launch(enable_queue=True)
174
+ demo.launch()