File size: 14,522 Bytes
13769af
 
 
 
 
 
b2776f5
13769af
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d3a3380
 
6ecd3ae
d3a3380
6ecd3ae
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13769af
 
 
 
 
 
 
 
 
 
 
 
 
 
b2776f5
13769af
 
b2776f5
 
13769af
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b2776f5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d3a3380
 
6ecd3ae
d3a3380
13769af
 
 
 
b2776f5
13769af
b2776f5
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
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
import vecs
from dotenv import load_dotenv
import os
import threading 
import base64
import os
import re
import threading
from google import genai
from google.genai import types
from sentence_transformers.SentenceTransformer import SentenceTransformer
import smtplib, ssl
from email.mime.text import MIMEText

load_dotenv()
user = os.getenv("user")
password = os.getenv("password")
host = os.getenv("host")
port = os.getenv("port")
mail = os.getenv("email")
APP_PASSWORD = os.getenv("app_password")
db_name = "postgres"
DB_CONNECTION = f"postgresql://{user}:{password}@{host}:{port}/{db_name}"
vx = vecs.create_client(DB_CONNECTION)
model = SentenceTransformer('Snowflake/snowflake-arctic-embed-xs', device="cpu")
client = genai.Client(api_key=os.getenv('GEMINI_API_KEY'))

respuesta = """
El documento "Preguntas Frecuentes: R茅gimen de Protecci贸n de la Competencia" de la Superintendencia de Industria y Comercio (SIC) se alinea y coordina con la descripci贸n proporcionada sobre la jurisprudencia constitucional colombiana en varios puntos clave.

Aqu铆 te presento la comparaci贸n:

**1. Principio Constitucional de la Libre Competencia y la Libre Empresa (Art铆culo 333 de la Constituci贸n):**

*   **Documento de la SIC:** El documento de la SIC hace referencia directa al **Art铆culo 333 de la Constituci贸n Pol铆tica** en la p谩gina 5. Lo cita expl铆citamente al responder la pregunta "驴De d贸nde provienen los derechos a la libre competencia y a la libertad econ贸mica?". Establece que este art铆culo consagra la libertad de empresa, libre competencia y libertad econ贸mica como derechos fundamentales.
*   **Descripci贸n de Jurisprudencia:** La descripci贸n de la jurisprudencia se帽ala que el **Art铆culo 333 de la Constituci贸n Pol铆tica es el fundamento principal** y que la Corte Constitucional ha reiterado que la libertad de competencia se despliega junto con la libertad de empresa. Tambi茅n menciona la obligaci贸n del Estado de impedir la obstrucci贸n de la libertad econ贸mica.

**Coordinaci贸n:** Existe una **coordinaci贸n directa y expl铆cita**. El documento de la SIC parte de la base constitucional que la jurisprudencia describe como fundamental. Ambos resaltan la importancia del Art铆culo 333 como el pilar de la protecci贸n de la competencia y la libertad de empresa en Colombia.

**2. Pr谩cticas Comerciales Restrictivas y su Prohibici贸n General:**

*   **Documento de la SIC:** El documento dedica un cap铆tulo entero (Cap铆tulo 3: "Pr谩cticas Restrictivas de la Competencia") a detallar las **conductas prohibidas**. Enumera acuerdos anticompetitivos (carteles, acuerdos horizontales y verticales), abuso de posici贸n dominante y ciertos actos unilaterales, as铆 como integraciones econ贸micas que restrinjan sustancialmente la competencia. Menciona el art铆culo 47 del Decreto 2153 de 1992 como fundamento de la ilegalidad de ciertos acuerdos.
*   **Descripci贸n de Jurisprudencia:** La descripci贸n de la jurisprudencia se refiere a la **prohibici贸n general de pr谩cticas que atenten contra la libre competencia**, citando la Sentencia C-032 de 2017 que analiz贸 y declar贸 exequible el art铆culo 1 de la Ley 155 de 1959 (que proh铆be "toda clase de pr谩cticas... tendientes a limitar la libre competencia y a mantener o determinar precios inequitativos"). Argumenta que esta prohibici贸n general es necesaria para proteger el derecho a la libre competencia.

**Coordinaci贸n:** Hay una **fuerte coordinaci贸n tem谩tica**. El documento de la SIC opera como una explicaci贸n detallada y aplicada de los principios generales que la jurisprudencia constitucional valida. La prohibici贸n general de pr谩cticas restrictivas, reconocida por la Corte, se desglosa en el documento de la SIC en conductas espec铆ficas y detalladas que son ilegales.

**3. Competencia Desleal:**

*   **Documento de la SIC:** El documento de la SIC menciona la **competencia desleal** en la p谩gina 8, al describir las conductas prohibidas. Indica que el r茅gimen de protecci贸n de la competencia contempla los "actos de Competencia Desleal establecidos en la Ley 256 de 1996 que afecten o tengan la capacidad para afectar el inter茅s general del mercado".
*   **Descripci贸n de Jurisprudencia:** La descripci贸n de la jurisprudencia dedica un punto completo a la **competencia desleal**, citando la Sentencia C-535 de 1997 que examin贸 el art铆culo 19 de la Ley 256 de 1996. Explica que la competencia desleal distorsiona las condiciones del mercado, afecta la libre decisi贸n de los consumidores y la equidad entre competidores, y que la libertad de empresa puede ser limitada para protegerla.

**Coordinaci贸n:** La coordinaci贸n es **tem谩tica y de reconocimiento de la normativa**. El documento de la SIC reconoce expl铆citamente que la Ley 256 de 1996, que regula la competencia desleal, es parte del marco de protecci贸n de la competencia. La jurisprudencia, a su vez, valida la constitucionalidad de esta ley y su objetivo.

**4. El Papel de las Superintendencias y la Administraci贸n de Justicia:**

*   **Documento de la SIC:** El documento explica en detalle las **funciones y facultades administrativas de la Superintendencia de Industria y Comercio** en materia de protecci贸n de la competencia. Describe c贸mo inicia investigaciones (Cap铆tulo 4), su procedimiento, y las facultades para practicar pruebas (p谩gina 14). Tambi茅n menciona las sanciones que puede imponer.
*   **Descripci贸n de Jurisprudencia:** La descripci贸n de la jurisprudencia aborda el **papel de las Superintendencias** y la administraci贸n de justicia, citando la Sentencia C-649 de 2001. Diferencia entre funciones jurisdiccionales y administrativas, y subraya la importancia de la independencia e imparcialidad de los funcionarios que ejercen funciones judiciales por excepci贸n.

**Coordinaci贸n:** La coordinaci贸n aqu铆 es **operativa y de legitimaci贸n**. El documento de la SIC detalla las funciones de la Superintendencia, que son las que la jurisprudencia constitucional ha analizado y validado en cuanto a su constitucionalidad, siempre y cuando se respeten los principios de legalidad, debido proceso e imparcialidad. El documento de la SIC describe c贸mo la SIC ejerce estas facultades de manera administrativa.

**5. Transici贸n Legislativa y la Vigencia de Normas Anteriores:**

*   **Documento de la SIC:** El documento de la SIC menciona la **Ley 155 de 1959** como una de las normas principales que contienen el r茅gimen de protecci贸n de la libre competencia (p谩gina 6).
*   **Descripci贸n de Jurisprudencia:** La descripci贸n de la jurisprudencia explica, citando la Sentencia C-590 de 1992, que la legislaci贸n preexistente (como la Ley 155 de 1959) contin煤a vigente si no es incompatible con la Constituci贸n de 1991, y que el juicio de constitucionalidad se realiza frente a la nueva Carta.

**Coordinaci贸n:** La coordinaci贸n es **hist贸rica y de reconocimiento normativo**. El documento de la SIC act煤a sobre la base de que normas antiguas pero vigentes, como la Ley 155 de 1959, son parte del marco legal aplicable, lo cual es respaldado por la jurisprudencia al explicar c贸mo estas normas siguen siendo relevantes post-Constituci贸n de 1991.

**En resumen:**

El documento de la SIC es la **manifestaci贸n pr谩ctica y aplicada de los principios y normas que la jurisprudencia constitucional colombiana ha interpretado y validado**. Ambos convergen en:

*   La **centralidad del Art铆culo 333 de la Constituci贸n** como fundamento.
*   La **necesidad de proteger la libre competencia** y prohibir pr谩cticas que la distorsionen.
*   La **inclusi贸n de la competencia desleal** dentro del espectro de protecci贸n del mercado.
*   La **legitimidad y el rol de la Superintendencia de Industria y Comercio** como autoridad encargada de velar por la competencia, siempre dentro de un marco legal y constitucional.
*   La **vigencia de normativas anteriores** que no contravienen la Constituci贸n actual.

El documento de la SIC puede considerarse como una explicaci贸n detallada y accesible de los conceptos y procedimientos que la jurisprudencia constitucional ha establecido como constitucionales y necesarios para el buen funcionamiento de la econom铆a de mercado en Colombia."""

def feedback(query, context, history):
    msg = MIMEText(f"""Hola, env铆o autom谩tico con SMTP.

    query: {query}

    context: {context}

    history: {history}
                   """, "plain", "utf-8")
    msg["Subject"] = "feedback"
    msg["From"] = mail
    msg["To"] = mail
    try: 
        with smtplib.SMTP_SSL("smtp.gmail.com", 465, context=ssl.create_default_context()) as server:
            server.login(mail, APP_PASSWORD)
            server.send_message(msg)
    except: 
       print(f'envio fallido {query}')

def query_db(query, limit = 5, filters = {}, measure = "cosine_distance", include_value = True, include_metadata=True, table = "2023"):
  query_embeds = vx.get_or_create_collection(name= table, dimension=384)
  ans = query_embeds.query(
      data=query,
      limit=limit,
      filters=filters,
      measure=measure,
      include_value=include_value,
      include_metadata=include_metadata,
  )
  return ans  

def sort_by_score(item):
  return item[1]

def infa帽o(rad):
  a = int(rad[len(rad)-2::])
  if  a > 89:
    return a + 1900
  else:
    return a + 2000

def thread_query(query, target, year):
  return target.extend(query_db(query, table=str(year))) 


def vector_query(query, start = 1992, end = 2024):
  results = []
  vector_query = model.encode(query)
  threads = []
  for i in range(start, end + 1):
    t = threading.Thread(target=thread_query, args=(vector_query, results, i))
    threads.append(t)
    t.start()
  threads[-1].join()
  results.sort(key=sort_by_score)
  q = {}
  for i in results:
    if i[2]['sentencia'] not in q.keys(): 
      q[i[2]['sentencia']] = 1
    else: 
      q[i[2]['sentencia']] += 1
  judgements = []

  for i in q.keys(): 
    if q[i] > 1:
      judgements.append(i)
  print(query, judgements)
  return judgements

def context_builder_prompt_constructor(judgement):
    return judgement

def context_builder(context_prompt, target):
    model = "gemini-2.5-flash-lite"
    contents = [
        types.Content(
            role="user",
            parts=[
                types.Part.from_text(text=context_prompt),
            ],
        ),
    ]
    tools = [
        types.Tool(googleSearch=types.GoogleSearch(
        )),]
    generate_content_config = types.GenerateContentConfig(
        thinking_config = types.ThinkingConfig(
            thinking_budget=0,
        ),
        tools=tools,
        system_instruction=[
            types.Part.from_text(text=f"""resume el contenido de la sentencia de forma detallada, mencionando todos los puntos considerados en la sentencia"""),
        ],
    )

    response = client.models.generate_content(
        model=model,
        contents=contents,
        config=generate_content_config,
    )
    return target.append(response.text)

def context_draft(judgements, query):
  context = []
  threads = []
  for i in judgements: 
    t = threading.Thread(target=context_builder, args=(context_builder_prompt_constructor(i), context))
    threads.append(t)
    t.start()
  
  while len(context) < len(threads): 
    pass

  draft = ''
  for i in context: 
    draft += i + '\n'
  return draft

def generate(query, context, message_history):
    model = "gemini-2.5-flash-lite"

    # Convert Hugging Face style message history to Gemini API format
    gemini_contents = []
    for message in message_history:
        role = "user" if message["role"] == "user" else "model"
        gemini_contents.append(
            types.Content(
                role=role,
                parts=[types.Part.from_text(text=message["content"])],
            )
        )

    # Add the current user query to the contents
    gemini_contents.append(
        types.Content(
            role="user",
            parts=[
                types.Part.from_text(text=query),
            ],
        )
    )


    generate_content_config = types.GenerateContentConfig(
        thinking_config = types.ThinkingConfig(
            thinking_budget=0,
        ),
        system_instruction=[
            types.Part.from_text(text=f"""Eres Ticio un asistente de investigaci贸n de jurisprudencia colombiana. Tienes acceso a un contexto especialmente dise帽ado para esta conversaci贸n. Tu tarea es contestar a las preguntas del usuario referenciando siempre las sentencias de donde viene la informaci贸n como si fueras un investigador experto.
{context}

""")]
    )

    response = client.models.generate_content(
        model=model,
        contents=gemini_contents,
        config=generate_content_config,
    )
    return response.text

def generate_links(judgments):
    output = []
    
    for judgment in judgments:
        # Match patterns like 'C-186-19', 'T-092-93', 'SU-000-20'
        match = re.match(r'([A-Za-z]+)-(\d{3})-(\d{2})', judgment)
        if match:
            type_code = match.group(1).lower()  # 'c', 't', 'su'
            number = match.group(2)
            year_suffix = match.group(3)
            
            # Determine full 4-digit year
            year = '20' + year_suffix if int(year_suffix) <= 68 else '19' + year_suffix
            
            # Format radicado for URL
            if type_code == 'su':
                radicado_url = f"su{number.zfill(3)}-{year_suffix}"
            else:
                radicado_url = f"{type_code}-{number}-{year_suffix}"  # note the dash after type
            
            # Build URL
            url = f"https://www.corteconstitucional.gov.co/relatoria/{year}/{radicado_url}.htm"
            
            # Append as a single sublist with judgment and url
            output.append([[judgment], [url]])
        else:
            print(f"Invalid format: {judgment}")
    
    return output

def link_constructor(judgements):
   return generate_links([x.rsplit('.rtf')[0] for x in judgements])

def inference(input, history, context, links):
  if len(input["files"]) > 0: 
     return respuesta, context, links
  query = input["text"]
  if context == None or len(context) <= 0 or len(history) <= 0:
    vector_query_results = vector_query(query)
    context = context_draft(vector_query_results, query)
    t = threading.Thread(target=feedback, args=(query, context, history))
    return generate(query, context, history), context, link_constructor(vector_query_results)
  else:
    return generate(query, context, history), context, links