Generates the Executive Report as required by the GenAI Challenge.
This endpoint acts as the main entry point for the AI reporting workflow.
It constructs a strict system prompt and delegates execution to the SRAGAgentOrchestrator.
Workflow:
- Prompt Construction: Injects a structured prompt ensuring the Agent calculates
4 key metrics (Case Increase, Mortality, ICU, Vaccination) and generates
2 mandatory charts (Trend, History).
- Context Injection: If
focus_area is provided in the request, it is appended
to the prompt to guide the news search.
- Execution: Runs the ReAct agent loop.
- Artifact Handling: Extracts generated plot filenames from the agent's output
and uploads artifacts (text + plots) to storage (MinIO/S3).
Parameters:
| Name |
Type |
Description |
Default |
request
|
ReportRequest
|
Input payload containing focus areas.
|
required
|
orchestrator
|
SRAGAgentOrchestrator
|
The dependency-injected agent orchestrator.
|
Depends(get_orchestrator)
|
Returns:
| Name | Type |
Description |
AgentResponse |
|
Object containing the generated markdown, list of plot paths,
|
|
|
|
Raises:
| Type |
Description |
HTTPException
|
If the agent execution fails or an internal error occurs (500).
|
Source code in api/src/routers/agent.py
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 | @router.post("/report", response_model=AgentResponse)
async def generate_report(
request: ReportRequest,
orchestrator: SRAGAgentOrchestrator = Depends(get_orchestrator),
):
"""
Generates the Executive Report as required by the GenAI Challenge.
This endpoint acts as the main entry point for the AI reporting workflow.
It constructs a strict system prompt and delegates execution to the `SRAGAgentOrchestrator`.
**Workflow:**
1. **Prompt Construction**: Injects a structured prompt ensuring the Agent calculates
4 key metrics (Case Increase, Mortality, ICU, Vaccination) and generates
2 mandatory charts (Trend, History).
2. **Context Injection**: If `focus_area` is provided in the request, it is appended
to the prompt to guide the news search.
3. **Execution**: Runs the ReAct agent loop.
4. **Artifact Handling**: Extracts generated plot filenames from the agent's output
and uploads artifacts (text + plots) to storage (MinIO/S3).
Args:
request (ReportRequest): Input payload containing focus areas.
orchestrator (SRAGAgentOrchestrator): The dependency-injected agent orchestrator.
Returns:
AgentResponse: Object containing the generated markdown, list of plot paths,
and execution metrics.
Raises:
HTTPException: If the agent execution fails or an internal error occurs (500).
"""
start_time = time.time()
tags = {
"genai.task": "executive_report",
"genai.focus_area": request.focus_area if request.focus_area else "general",
}
set_trace_tags(tags)
report_prompt = (
"Generate a comprehensive **Executive Report** on the current **SRAG situation**.\n"
"STRICTLY FOLLOW this structure and formatting rules:\n\n"
"1. **KEY METRICS**: Calculate and present:\n"
" - Case Increase Rate (Growth %)\n"
" - Mortality Rate (CFR %)\n"
" - ICU Occupation Rate (%)\n"
" - Vaccination Rate for COVID-19 (%)\n"
" - Vaccination Rate for Influenza (Flu) (%)\n\n"
"2. **VISUAL ANALYSIS** (Mandatory):\n"
" - You MUST generate two charts: 'trend_30d' and 'history_12m'.\n"
" - **IMPORTANT:** When embedding charts, use the EXACT filename returned by the tool (including .png):\n"
" ``\n"
" - Do NOT use the local 'data/plots/' path in the Markdown link.\n\n"
"3. **CONTEXTUAL ANALYSIS**:\n"
" Make web search to find relevant news (e.g., outbreaks, variants, public health events)\n"
" to provide context and support for the presented metrics, helping explain observed trends\n"
" and anomalies in the data.\n\n"
"4. **CONCLUSION**: Brief executive summary. "
"5. **OUTPUT FORMAT**:\n"
" - The report includes only the analytical sections defined above.\n"
" - The content is written in a neutral, report-style format.\n"
" - The document finishes at the conclusion section."
)
if request.focus_area:
report_prompt += (
f"\n\nAdditional Focus: Please specifically analyze {request.focus_area}."
)
try:
result = await orchestrator.run(report_prompt)
generated_plots = extract_plots_from_result(result)
response_text = result.output
upload_run_artifacts(response_text, generated_plots)
return AgentResponse(
response=response_text,
plots=generated_plots,
execution_time=time.time() - start_time,
)
except Exception as e:
logger.error(f"Report generation failed: {e}", exc_info=True)
raise HTTPException(status_code=500, detail=str(e))
|