Álvaro Valenzuela Valdes commited on
Commit ·
ce0ad80
1
Parent(s): aa38935
Add Requirement Response (Q&A Style) feature for document analysis
Browse files
backend/app/schemas/analysis.py
CHANGED
|
@@ -19,6 +19,11 @@ class ActionItem(BaseModel):
|
|
| 19 |
timeline: str
|
| 20 |
|
| 21 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
class AnalysisRequest(BaseModel):
|
| 23 |
tender: Tender
|
| 24 |
company_profile: CompanyProfile
|
|
@@ -37,6 +42,7 @@ class AnalysisResult(BaseModel):
|
|
| 37 |
proposal_draft: str
|
| 38 |
report_markdown: str
|
| 39 |
strategic_roadmap: str | None = None
|
|
|
|
| 40 |
audit_log: List[str] = []
|
| 41 |
|
| 42 |
|
|
|
|
| 19 |
timeline: str
|
| 20 |
|
| 21 |
|
| 22 |
+
class QAResponse(BaseModel):
|
| 23 |
+
question: str
|
| 24 |
+
answer: str
|
| 25 |
+
|
| 26 |
+
|
| 27 |
class AnalysisRequest(BaseModel):
|
| 28 |
tender: Tender
|
| 29 |
company_profile: CompanyProfile
|
|
|
|
| 42 |
proposal_draft: str
|
| 43 |
report_markdown: str
|
| 44 |
strategic_roadmap: str | None = None
|
| 45 |
+
requirement_responses: List[QAResponse] = []
|
| 46 |
audit_log: List[str] = []
|
| 47 |
|
| 48 |
|
backend/app/services/agents.py
CHANGED
|
@@ -76,10 +76,14 @@ async def run_full_analysis(tender: Tender, company_profile: CompanyProfile, doc
|
|
| 76 |
f"REPORTE LEGAL: {legal_resp}\n\n"
|
| 77 |
f"REPORTE TÉCNICO: {tech_resp}\n\n"
|
| 78 |
f"REPORTE ESTRATÉGICO: {strat_resp}\n\n"
|
| 79 |
-
f"
|
| 80 |
-
f"
|
| 81 |
-
f"
|
| 82 |
-
f"
|
|
|
|
|
|
|
|
|
|
|
|
|
| 83 |
f"Responde ÚNICAMENTE con el JSON."
|
| 84 |
)
|
| 85 |
|
|
|
|
| 76 |
f"REPORTE LEGAL: {legal_resp}\n\n"
|
| 77 |
f"REPORTE TÉCNICO: {tech_resp}\n\n"
|
| 78 |
f"REPORTE ESTRATÉGICO: {strat_resp}\n\n"
|
| 79 |
+
f"DATOS DE LA EMPRESA: {company_profile.model_dump_json()}\n\n"
|
| 80 |
+
f"INSTRUCCIONES CRÍTICAS:\n"
|
| 81 |
+
f"1. Genera el AnalysisResult final en JSON.\n"
|
| 82 |
+
f"2. Identifica 3-5 preguntas o requerimientos críticos del texto de las bases (o del contexto) y genera respuestas en estilo 'Q&A'.\n"
|
| 83 |
+
f"3. Cada respuesta debe usar los datos reales de la empresa (RUT, experiencia, etc.) para responder de forma profesional.\n"
|
| 84 |
+
f"4. El campo en el JSON debe ser 'requirement_responses' como una lista de {{'question', 'answer'}}.\n"
|
| 85 |
+
f"5. Ejemplo: {{'question': '¿Cuenta con RUT vigente?', 'answer': 'SÍ, nuestra empresa posee RUT 77... y está habilitada en el SII.'}}\n"
|
| 86 |
+
f"6. Incluye un 'strategic_roadmap' con 3 fases.\n"
|
| 87 |
f"Responde ÚNICAMENTE con el JSON."
|
| 88 |
)
|
| 89 |
|
frontend/components/AgentAnalysis.tsx
CHANGED
|
@@ -343,6 +343,30 @@ export default function AgentAnalysis({ tender, companyProfile, analysis, onAnal
|
|
| 343 |
<p className="text-slate-300 text-xl leading-relaxed italic border-l-4 border-purple-500 pl-8">{analysis.executive_summary}</p>
|
| 344 |
</div>
|
| 345 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 346 |
{/* Proposal Draft Section */}
|
| 347 |
{analysis.proposal_draft && (
|
| 348 |
<div className="mt-12 space-y-6">
|
|
|
|
| 343 |
<p className="text-slate-300 text-xl leading-relaxed italic border-l-4 border-purple-500 pl-8">{analysis.executive_summary}</p>
|
| 344 |
</div>
|
| 345 |
|
| 346 |
+
{/* Requirement Q&A Section */}
|
| 347 |
+
{analysis.requirement_responses && analysis.requirement_responses.length > 0 && (
|
| 348 |
+
<div className="mt-12 space-y-6">
|
| 349 |
+
<div className="flex items-center gap-3 border-b border-white/5 pb-4">
|
| 350 |
+
<span className="text-2xl">📋</span>
|
| 351 |
+
<h4 className="text-[11px] font-bold uppercase tracking-widest text-purple-400">Requirement Response (Q&A Style)</h4>
|
| 352 |
+
</div>
|
| 353 |
+
<div className="grid gap-4">
|
| 354 |
+
{analysis.requirement_responses.map((item, i) => (
|
| 355 |
+
<div key={i} className="rounded-2xl bg-white/[0.03] border border-white/5 p-6 hover:border-purple-500/30 transition-all group">
|
| 356 |
+
<div className="flex gap-4">
|
| 357 |
+
<span className="text-purple-500 font-bold font-mono">Q.</span>
|
| 358 |
+
<p className="text-white font-semibold text-sm">{item.question}</p>
|
| 359 |
+
</div>
|
| 360 |
+
<div className="mt-4 flex gap-4 pl-8 border-l border-white/10">
|
| 361 |
+
<span className="text-green-400 font-bold font-mono">A.</span>
|
| 362 |
+
<p className="text-slate-400 text-sm leading-relaxed">{item.answer}</p>
|
| 363 |
+
</div>
|
| 364 |
+
</div>
|
| 365 |
+
))}
|
| 366 |
+
</div>
|
| 367 |
+
</div>
|
| 368 |
+
)}
|
| 369 |
+
|
| 370 |
{/* Proposal Draft Section */}
|
| 371 |
{analysis.proposal_draft && (
|
| 372 |
<div className="mt-12 space-y-6">
|
frontend/lib/types.ts
CHANGED
|
@@ -56,6 +56,11 @@ export type ActionItem = {
|
|
| 56 |
timeline: string;
|
| 57 |
};
|
| 58 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 59 |
export type AnalysisResult = {
|
| 60 |
fit_score: number;
|
| 61 |
decision: string;
|
|
@@ -67,6 +72,7 @@ export type AnalysisResult = {
|
|
| 67 |
proposal_draft: string;
|
| 68 |
report_markdown: string;
|
| 69 |
strategic_roadmap?: string;
|
|
|
|
| 70 |
audit_log: string[];
|
| 71 |
};
|
| 72 |
|
|
|
|
| 56 |
timeline: string;
|
| 57 |
};
|
| 58 |
|
| 59 |
+
export type QAResponse = {
|
| 60 |
+
question: string;
|
| 61 |
+
answer: string;
|
| 62 |
+
};
|
| 63 |
+
|
| 64 |
export type AnalysisResult = {
|
| 65 |
fit_score: number;
|
| 66 |
decision: string;
|
|
|
|
| 72 |
proposal_draft: string;
|
| 73 |
report_markdown: string;
|
| 74 |
strategic_roadmap?: string;
|
| 75 |
+
requirement_responses?: QAResponse[];
|
| 76 |
audit_log: string[];
|
| 77 |
};
|
| 78 |
|