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