Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -299,56 +299,49 @@ class UniversalProcurementAgent:
|
|
| 299 |
self.analytics = ProcurementAnalytics(po_df)
|
| 300 |
|
| 301 |
def executive_summary(self) -> str:
|
| 302 |
-
|
| 303 |
-
|
| 304 |
-
|
| 305 |
-
|
| 306 |
-
|
| 307 |
-
|
| 308 |
-
|
| 309 |
-
|
| 310 |
-
|
| 311 |
-
|
| 312 |
-
|
| 313 |
-
|
| 314 |
-
|
| 315 |
-
|
| 316 |
-
|
| 317 |
-
|
| 318 |
-
{
|
| 319 |
-
"role": "system",
|
| 320 |
-
"content": (
|
| 321 |
-
"You are a senior procurement analyst. Use bullet points, be concise, "
|
| 322 |
-
"and always use the ₹ symbol. When summarizing, include top categories "
|
| 323 |
-
"and vendors with percentages, then 2-3 quantified actions."
|
| 324 |
-
),
|
| 325 |
-
},
|
| 326 |
-
{
|
| 327 |
-
"role": "user",
|
| 328 |
-
"content": (
|
| 329 |
-
{
|
| 330 |
-
"role": "user",
|
| 331 |
-
"content": (
|
| 332 |
-
"Executive summary. Format amounts with commas (e.g., ₹12,34,567).\n\n"
|
| 333 |
-
f"Data: {json.dumps(data_summary)}"
|
| 334 |
-
),
|
| 335 |
-
},
|
| 336 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 337 |
|
| 338 |
-
|
| 339 |
-
|
| 340 |
-
|
| 341 |
-
|
| 342 |
-
|
| 343 |
-
|
| 344 |
-
|
| 345 |
-
"🧠 **[AI-Powered Analysis]**
|
| 346 |
|
| 347 |
-
"
|
| 348 |
-
+ self.llm.chat(messages, max_tokens=550)
|
| 349 |
-
)
|
| 350 |
-
except Exception as e:
|
| 351 |
-
return self._rule_summary() + f"
|
| 352 |
|
| 353 |
*AI fallback due to: {e}*"
|
| 354 |
|
|
|
|
| 299 |
self.analytics = ProcurementAnalytics(po_df)
|
| 300 |
|
| 301 |
def executive_summary(self) -> str:
|
| 302 |
+
if not self.llm.available:
|
| 303 |
+
return self._rule_summary()
|
| 304 |
+
|
| 305 |
+
k = self.analytics.kpis()
|
| 306 |
+
top_cats = self.analytics.top_n_categories(3)
|
| 307 |
+
top_vens = self.analytics.top_n_vendors(3)
|
| 308 |
+
data_summary = {
|
| 309 |
+
"total_spend": k['total_spend'],
|
| 310 |
+
"total_orders": int(len(self.po_data)),
|
| 311 |
+
"vendor_count": int(self.po_data['vendor'].nunique()),
|
| 312 |
+
"avg_order_value": k['avg_order_value'],
|
| 313 |
+
"on_time_delivery": k['on_time_rate'],
|
| 314 |
+
"avg_quality": k['quality_avg'],
|
| 315 |
+
"top_categories": top_cats,
|
| 316 |
+
"top_vendors": top_vens,
|
| 317 |
+
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 318 |
|
| 319 |
+
messages = [
|
| 320 |
+
{
|
| 321 |
+
"role": "system",
|
| 322 |
+
"content": (
|
| 323 |
+
"You are a senior procurement analyst. Use bullet points, be concise, "
|
| 324 |
+
"and always use the ₹ symbol. When summarizing, include top categories "
|
| 325 |
+
"and vendors with percentages, then 2-3 quantified actions."
|
| 326 |
+
),
|
| 327 |
+
},
|
| 328 |
+
{
|
| 329 |
+
"role": "user",
|
| 330 |
+
"content": (
|
| 331 |
+
"Executive summary. Format amounts with commas (e.g., ₹12,34,567).\n\n"
|
| 332 |
+
f"Data: {json.dumps(data_summary)}"
|
| 333 |
+
),
|
| 334 |
+
},
|
| 335 |
+
]
|
| 336 |
|
| 337 |
+
try:
|
| 338 |
+
return (
|
| 339 |
+
"🧠 **[AI-Powered Analysis]**\n\n"
|
| 340 |
+
+ self.llm.chat(messages, max_tokens=550)
|
| 341 |
+
)
|
| 342 |
+
except Exception as e:
|
| 343 |
+
return self._rule_summary() + f"\n\n*AI fallback due to: {e}*"
|
|
|
|
| 344 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 345 |
|
| 346 |
*AI fallback due to: {e}*"
|
| 347 |
|