Deploy from GitHub Actions
Browse files- src/rag.py +2 -4
- src/utils/utils.py +102 -24
src/rag.py
CHANGED
|
@@ -389,7 +389,7 @@ class RogerRAG:
|
|
| 389 |
}
|
| 390 |
|
| 391 |
current_date = datetime.now().strftime("%B %d, %Y")
|
| 392 |
-
|
| 393 |
# Build system prompt with context embedded
|
| 394 |
system_content = f"""You are Roger, an AI intelligence analyst for Sri Lanka.
|
| 395 |
|
|
@@ -424,9 +424,7 @@ Context:
|
|
| 424 |
|
| 425 |
try:
|
| 426 |
chain = rag_prompt | self.llm | StrOutputParser()
|
| 427 |
-
answer = chain.invoke(
|
| 428 |
-
{"history": history_messages, "question": question}
|
| 429 |
-
)
|
| 430 |
|
| 431 |
self.chat_history.append((question, answer))
|
| 432 |
|
|
|
|
| 389 |
}
|
| 390 |
|
| 391 |
current_date = datetime.now().strftime("%B %d, %Y")
|
| 392 |
+
|
| 393 |
# Build system prompt with context embedded
|
| 394 |
system_content = f"""You are Roger, an AI intelligence analyst for Sri Lanka.
|
| 395 |
|
|
|
|
| 424 |
|
| 425 |
try:
|
| 426 |
chain = rag_prompt | self.llm | StrOutputParser()
|
| 427 |
+
answer = chain.invoke({"history": history_messages, "question": question})
|
|
|
|
|
|
|
| 428 |
|
| 429 |
self.chat_history.append((question, answer))
|
| 430 |
|
src/utils/utils.py
CHANGED
|
@@ -1632,7 +1632,9 @@ def tool_commodity_prices() -> Dict[str, Any]:
|
|
| 1632 |
|
| 1633 |
if rows:
|
| 1634 |
# Get the latest date in the dataset
|
| 1635 |
-
latest_date = max(
|
|
|
|
|
|
|
| 1636 |
data_date = latest_date
|
| 1637 |
|
| 1638 |
# Get the latest prices for each commodity (average across markets)
|
|
@@ -1649,7 +1651,9 @@ def tool_commodity_prices() -> Dict[str, Any]:
|
|
| 1649 |
# Calculate average prices and build commodity list
|
| 1650 |
for wfp_name, (display_name, category) in COMMODITY_MAPPING.items():
|
| 1651 |
if wfp_name in latest_prices and latest_prices[wfp_name]:
|
| 1652 |
-
avg_price = sum(latest_prices[wfp_name]) / len(
|
|
|
|
|
|
|
| 1653 |
unit = "LKR/kg"
|
| 1654 |
if "Eggs" in display_name:
|
| 1655 |
unit = "LKR/each"
|
|
@@ -1660,18 +1664,22 @@ def tool_commodity_prices() -> Dict[str, Any]:
|
|
| 1660 |
elif "Diesel" in display_name or "Petrol" in display_name:
|
| 1661 |
unit = "LKR/L"
|
| 1662 |
|
| 1663 |
-
commodities.append(
|
| 1664 |
-
|
| 1665 |
-
|
| 1666 |
-
|
| 1667 |
-
|
| 1668 |
-
|
| 1669 |
-
|
| 1670 |
-
|
| 1671 |
-
|
|
|
|
|
|
|
| 1672 |
|
| 1673 |
source_status = "live"
|
| 1674 |
-
logger.info(
|
|
|
|
|
|
|
| 1675 |
|
| 1676 |
except Exception as e:
|
| 1677 |
logger.warning(f"[COMMODITY] WFP API error: {e}")
|
|
@@ -1682,22 +1690,92 @@ def tool_commodity_prices() -> Dict[str, Any]:
|
|
| 1682 |
logger.info("[COMMODITY] Using baseline data - WFP API unavailable")
|
| 1683 |
source_status = "baseline"
|
| 1684 |
commodities = [
|
| 1685 |
-
{
|
| 1686 |
-
|
| 1687 |
-
|
| 1688 |
-
|
| 1689 |
-
|
| 1690 |
-
|
| 1691 |
-
|
| 1692 |
-
{
|
| 1693 |
-
|
| 1694 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1695 |
]
|
| 1696 |
data_date = utc_now().strftime("%Y-%m-%d")
|
| 1697 |
|
| 1698 |
# Sort by category
|
| 1699 |
-
category_order = {
|
| 1700 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1701 |
|
| 1702 |
# Build result
|
| 1703 |
live_count = sum(1 for c in commodities if c.get("live", False))
|
|
|
|
| 1632 |
|
| 1633 |
if rows:
|
| 1634 |
# Get the latest date in the dataset
|
| 1635 |
+
latest_date = max(
|
| 1636 |
+
row.get("date", "") for row in rows if row.get("date")
|
| 1637 |
+
)
|
| 1638 |
data_date = latest_date
|
| 1639 |
|
| 1640 |
# Get the latest prices for each commodity (average across markets)
|
|
|
|
| 1651 |
# Calculate average prices and build commodity list
|
| 1652 |
for wfp_name, (display_name, category) in COMMODITY_MAPPING.items():
|
| 1653 |
if wfp_name in latest_prices and latest_prices[wfp_name]:
|
| 1654 |
+
avg_price = sum(latest_prices[wfp_name]) / len(
|
| 1655 |
+
latest_prices[wfp_name]
|
| 1656 |
+
)
|
| 1657 |
unit = "LKR/kg"
|
| 1658 |
if "Eggs" in display_name:
|
| 1659 |
unit = "LKR/each"
|
|
|
|
| 1664 |
elif "Diesel" in display_name or "Petrol" in display_name:
|
| 1665 |
unit = "LKR/L"
|
| 1666 |
|
| 1667 |
+
commodities.append(
|
| 1668 |
+
{
|
| 1669 |
+
"name": display_name,
|
| 1670 |
+
"price": round(avg_price, 2),
|
| 1671 |
+
"unit": unit,
|
| 1672 |
+
"category": category,
|
| 1673 |
+
"live": True,
|
| 1674 |
+
"wfp_commodity": wfp_name,
|
| 1675 |
+
"markets_sampled": len(latest_prices[wfp_name]),
|
| 1676 |
+
}
|
| 1677 |
+
)
|
| 1678 |
|
| 1679 |
source_status = "live"
|
| 1680 |
+
logger.info(
|
| 1681 |
+
f"[COMMODITY] ✓ Fetched {len(commodities)} live prices from WFP (data date: {latest_date})"
|
| 1682 |
+
)
|
| 1683 |
|
| 1684 |
except Exception as e:
|
| 1685 |
logger.warning(f"[COMMODITY] WFP API error: {e}")
|
|
|
|
| 1690 |
logger.info("[COMMODITY] Using baseline data - WFP API unavailable")
|
| 1691 |
source_status = "baseline"
|
| 1692 |
commodities = [
|
| 1693 |
+
{
|
| 1694 |
+
"name": "White Rice (Nadu)",
|
| 1695 |
+
"price": 220,
|
| 1696 |
+
"unit": "LKR/kg",
|
| 1697 |
+
"category": "grains",
|
| 1698 |
+
"live": False,
|
| 1699 |
+
},
|
| 1700 |
+
{
|
| 1701 |
+
"name": "White Rice (Samba)",
|
| 1702 |
+
"price": 250,
|
| 1703 |
+
"unit": "LKR/kg",
|
| 1704 |
+
"category": "grains",
|
| 1705 |
+
"live": False,
|
| 1706 |
+
},
|
| 1707 |
+
{
|
| 1708 |
+
"name": "Red Rice",
|
| 1709 |
+
"price": 240,
|
| 1710 |
+
"unit": "LKR/kg",
|
| 1711 |
+
"category": "grains",
|
| 1712 |
+
"live": False,
|
| 1713 |
+
},
|
| 1714 |
+
{
|
| 1715 |
+
"name": "Sugar (White)",
|
| 1716 |
+
"price": 240,
|
| 1717 |
+
"unit": "LKR/kg",
|
| 1718 |
+
"category": "essentials",
|
| 1719 |
+
"live": False,
|
| 1720 |
+
},
|
| 1721 |
+
{
|
| 1722 |
+
"name": "Dhal (Lentils)",
|
| 1723 |
+
"price": 380,
|
| 1724 |
+
"unit": "LKR/kg",
|
| 1725 |
+
"category": "pulses",
|
| 1726 |
+
"live": False,
|
| 1727 |
+
},
|
| 1728 |
+
{
|
| 1729 |
+
"name": "Coconut Oil",
|
| 1730 |
+
"price": 680,
|
| 1731 |
+
"unit": "LKR/L",
|
| 1732 |
+
"category": "cooking",
|
| 1733 |
+
"live": False,
|
| 1734 |
+
},
|
| 1735 |
+
{
|
| 1736 |
+
"name": "Eggs (per unit)",
|
| 1737 |
+
"price": 48,
|
| 1738 |
+
"unit": "LKR/each",
|
| 1739 |
+
"category": "protein",
|
| 1740 |
+
"live": False,
|
| 1741 |
+
},
|
| 1742 |
+
{
|
| 1743 |
+
"name": "Chicken",
|
| 1744 |
+
"price": 1350,
|
| 1745 |
+
"unit": "LKR/kg",
|
| 1746 |
+
"category": "protein",
|
| 1747 |
+
"live": False,
|
| 1748 |
+
},
|
| 1749 |
+
{
|
| 1750 |
+
"name": "Big Onion",
|
| 1751 |
+
"price": 280,
|
| 1752 |
+
"unit": "LKR/kg",
|
| 1753 |
+
"category": "vegetables",
|
| 1754 |
+
"live": False,
|
| 1755 |
+
},
|
| 1756 |
+
{
|
| 1757 |
+
"name": "Potatoes",
|
| 1758 |
+
"price": 350,
|
| 1759 |
+
"unit": "LKR/kg",
|
| 1760 |
+
"category": "vegetables",
|
| 1761 |
+
"live": False,
|
| 1762 |
+
},
|
| 1763 |
]
|
| 1764 |
data_date = utc_now().strftime("%Y-%m-%d")
|
| 1765 |
|
| 1766 |
# Sort by category
|
| 1767 |
+
category_order = {
|
| 1768 |
+
"grains": 1,
|
| 1769 |
+
"essentials": 2,
|
| 1770 |
+
"pulses": 3,
|
| 1771 |
+
"cooking": 4,
|
| 1772 |
+
"protein": 5,
|
| 1773 |
+
"vegetables": 6,
|
| 1774 |
+
"fuel": 7,
|
| 1775 |
+
}
|
| 1776 |
+
commodities.sort(
|
| 1777 |
+
key=lambda x: (category_order.get(x.get("category", ""), 99), x.get("name", ""))
|
| 1778 |
+
)
|
| 1779 |
|
| 1780 |
# Build result
|
| 1781 |
live_count = sum(1 for c in commodities if c.get("live", False))
|