脕lvaro Valenzuela Valdes commited on
Commit 路
9bdb2e0
1
Parent(s): 20b62f0
馃殌 Feature: Synthetic tender generation with coherent documents
Browse files- backend/app/services/llm.py +53 -0
backend/app/services/llm.py
CHANGED
|
@@ -305,3 +305,56 @@ async def generate_proposal_draft(analysis: dict, company: CompanyProfile) -> st
|
|
| 305 |
"""
|
| 306 |
|
| 307 |
return await call_gemini_with_model(prompt, model_name="Llama-3.3-70B (Groq)" if settings.groq_api_key else "Gemini 2.5 Flash")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 305 |
"""
|
| 306 |
|
| 307 |
return await call_gemini_with_model(prompt, model_name="Llama-3.3-70B (Groq)" if settings.groq_api_key else "Gemini 2.5 Flash")
|
| 308 |
+
|
| 309 |
+
async def generate_synthetic_tenders(keyword: str) -> List[Tender]:
|
| 310 |
+
"""
|
| 311 |
+
Generates realistic synthetic tenders with coherent bidding documents (bases)
|
| 312 |
+
when official sources are unavailable or empty.
|
| 313 |
+
"""
|
| 314 |
+
prompt = f"""
|
| 315 |
+
Genera 4 licitaciones de Mercado P煤blico CHILE realistas para el rubro: {keyword}
|
| 316 |
+
|
| 317 |
+
Para cada licitaci贸n, genera un JSON con:
|
| 318 |
+
- code: Formato XXXXX-XX-XX26
|
| 319 |
+
- name: Nombre profesional
|
| 320 |
+
- buyer: Una instituci贸n p煤blica chilena real
|
| 321 |
+
- description: UN DOCUMENTO EXTENSO de 'Bases Administrativas y T茅cnicas' (m铆nimo 300 palabras)
|
| 322 |
+
que incluya: Objeto de licitaci贸n, Requisitos t茅cnicos, Plazos, Multas y Criterios de Evaluaci贸n.
|
| 323 |
+
- status: 'Publicada'
|
| 324 |
+
- closing_date: ISO date en 2 semanas
|
| 325 |
+
- estimated_amount: Monto en CLP entre 5M y 50M
|
| 326 |
+
- region: Una regi贸n de Chile
|
| 327 |
+
|
| 328 |
+
RESPONDE SOLO EL JSON (Lista de objetos).
|
| 329 |
+
"""
|
| 330 |
+
|
| 331 |
+
res = await call_gemini(prompt, is_json=True)
|
| 332 |
+
items = []
|
| 333 |
+
try:
|
| 334 |
+
data = json.loads(res)
|
| 335 |
+
# Handle if LLM wraps in a key
|
| 336 |
+
if isinstance(data, dict):
|
| 337 |
+
for v in data.values():
|
| 338 |
+
if isinstance(v, list):
|
| 339 |
+
data = v
|
| 340 |
+
break
|
| 341 |
+
|
| 342 |
+
for i in data:
|
| 343 |
+
items.append(Tender(
|
| 344 |
+
code=i.get("code", "000-00-00"),
|
| 345 |
+
name=i.get("name", "Licitaci贸n Sint茅tica"),
|
| 346 |
+
description=i.get("description", "Documento de bases en proceso..."),
|
| 347 |
+
buyer=i.get("buyer", "Organismo P煤blico"),
|
| 348 |
+
status=i.get("status", "Publicada"),
|
| 349 |
+
closing_date=i.get("closing_date", datetime.now().isoformat()),
|
| 350 |
+
estimated_amount=float(i.get("estimated_amount", 0)),
|
| 351 |
+
source="AndesOps AI - Intelligent Discovery",
|
| 352 |
+
region=i.get("region", "Nacional"),
|
| 353 |
+
sector="Privado/P煤blico",
|
| 354 |
+
items=[],
|
| 355 |
+
attachments=[]
|
| 356 |
+
))
|
| 357 |
+
except Exception as e:
|
| 358 |
+
print(f"Error generating synthetic tenders: {e}")
|
| 359 |
+
|
| 360 |
+
return items
|