Spaces:
Sleeping
Sleeping
Upload 8 files
Browse files- .gitignore +50 -0
- agent.py +13 -0
- app.py +50 -0
- llm.py +19 -0
- main.py +60 -0
- prompts.py +38 -0
- requirements.txt +0 -0
- tools.py +168 -0
.gitignore
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Byte-compiled / optimized / compiled files
|
| 2 |
+
__pycache__/
|
| 3 |
+
*.pyc
|
| 4 |
+
*.pyd
|
| 5 |
+
*.pyo
|
| 6 |
+
*.egg-info/
|
| 7 |
+
.pytest_cache/
|
| 8 |
+
|
| 9 |
+
# Virtual environment
|
| 10 |
+
.venv/
|
| 11 |
+
env/
|
| 12 |
+
venv/
|
| 13 |
+
*.egg
|
| 14 |
+
*.whl
|
| 15 |
+
|
| 16 |
+
# Editor and IDE configurations
|
| 17 |
+
.vscode/
|
| 18 |
+
.idea/
|
| 19 |
+
.DS_Store
|
| 20 |
+
|
| 21 |
+
# Environment variables
|
| 22 |
+
.env
|
| 23 |
+
.env.*
|
| 24 |
+
# For example: .env.local, .env.development, .env.production
|
| 25 |
+
|
| 26 |
+
# Database files
|
| 27 |
+
*.sqlite3
|
| 28 |
+
*.db
|
| 29 |
+
# Add specific database files if applicable, e.g., for SQLite:
|
| 30 |
+
# instance/*.sqlite
|
| 31 |
+
|
| 32 |
+
# Logs and temporary files
|
| 33 |
+
*.log
|
| 34 |
+
tmp/
|
| 35 |
+
logs/
|
| 36 |
+
|
| 37 |
+
# Test reports
|
| 38 |
+
.coverage
|
| 39 |
+
htmlcov/
|
| 40 |
+
|
| 41 |
+
# Build artifacts
|
| 42 |
+
dist/
|
| 43 |
+
build/
|
| 44 |
+
|
| 45 |
+
# Uploaded media (if applicable)
|
| 46 |
+
# media/
|
| 47 |
+
# uploads/
|
| 48 |
+
|
| 49 |
+
# Specific to FastAPI/Uvicorn
|
| 50 |
+
.uvicorn_pid
|
agent.py
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Import the pre-built agent creator
|
| 2 |
+
from langgraph.prebuilt import create_react_agent
|
| 3 |
+
|
| 4 |
+
# Import your model and tools from other files
|
| 5 |
+
from llm import model
|
| 6 |
+
from tools import all_tools
|
| 7 |
+
|
| 8 |
+
from prompts import SYSTEM_PROMPT as system_prompt
|
| 9 |
+
|
| 10 |
+
# Create the agent using the model, tools, and the new system prompt
|
| 11 |
+
app = create_react_agent(model=model, tools=all_tools, prompt=system_prompt)
|
| 12 |
+
|
| 13 |
+
print("Pre-built ReAct agent created successfully!")
|
app.py
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import requests
|
| 2 |
+
import gradio as gr
|
| 3 |
+
import uuid
|
| 4 |
+
|
| 5 |
+
# The URL of your running FastAPI backend
|
| 6 |
+
BACKEND_URL = "http://127.0.0.1:8000/invoke"
|
| 7 |
+
|
| 8 |
+
# Generate a unique session ID for the entire chat session
|
| 9 |
+
SESSION_ID = str(uuid.uuid4())
|
| 10 |
+
|
| 11 |
+
print(f"New chat session started with ID: {SESSION_ID}")
|
| 12 |
+
|
| 13 |
+
def get_agent_response(message, history):
|
| 14 |
+
"""
|
| 15 |
+
This function is called every time the user sends a message.
|
| 16 |
+
It calls your FastAPI backend and returns the agent's response.
|
| 17 |
+
"""
|
| 18 |
+
# The payload to send to your backend
|
| 19 |
+
payload = {
|
| 20 |
+
"query": message,
|
| 21 |
+
"session_id": SESSION_ID
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
try:
|
| 25 |
+
# Make the API call to your backend
|
| 26 |
+
response = requests.post(BACKEND_URL, json=payload)
|
| 27 |
+
response.raise_for_status() # Raise an exception for bad status codes (4xx or 5xx)
|
| 28 |
+
|
| 29 |
+
# Extract the agent's response text from the JSON
|
| 30 |
+
return response.json()["response"]
|
| 31 |
+
|
| 32 |
+
except requests.exceptions.RequestException as e:
|
| 33 |
+
print(f"Error calling backend: {e}")
|
| 34 |
+
return "Sorry, there was an error connecting to the agent. Please check the backend server."
|
| 35 |
+
|
| 36 |
+
# Create the Gradio Chat Interface
|
| 37 |
+
chatbot_ui = gr.ChatInterface(
|
| 38 |
+
fn=get_agent_response,
|
| 39 |
+
title="Sarvam AI Agent",
|
| 40 |
+
description="Ask me about horoscopes, holidays, and more!",
|
| 41 |
+
examples=[
|
| 42 |
+
"What is the horoscope for Leo today?",
|
| 43 |
+
"Tell me the panchang for today",
|
| 44 |
+
"What are the Indian holidays in 2025?"
|
| 45 |
+
]
|
| 46 |
+
)
|
| 47 |
+
|
| 48 |
+
# Launch the UI
|
| 49 |
+
if __name__ == "__main__":
|
| 50 |
+
chatbot_ui.launch()
|
llm.py
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
from dotenv import load_dotenv
|
| 3 |
+
from langchain_openai import ChatOpenAI
|
| 4 |
+
|
| 5 |
+
load_dotenv()
|
| 6 |
+
|
| 7 |
+
SARVAM_API_KEY = os.getenv("SARVAM_API_KEY")
|
| 8 |
+
|
| 9 |
+
if not SARVAM_API_KEY:
|
| 10 |
+
raise ValueError("SARVAM_API_KEY not found in .env file. Please make sure it's set.")
|
| 11 |
+
|
| 12 |
+
model = ChatOpenAI(
|
| 13 |
+
model="sarvam-m",
|
| 14 |
+
api_key=SARVAM_API_KEY,
|
| 15 |
+
base_url="https://api.sarvam.ai/v1",
|
| 16 |
+
temperature=0.2,
|
| 17 |
+
)
|
| 18 |
+
|
| 19 |
+
print("Sarvam AI model initialized successfully using ChatOpenAI client.")
|
main.py
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from fastapi import FastAPI
|
| 2 |
+
from pydantic import BaseModel
|
| 3 |
+
from typing import List, Tuple
|
| 4 |
+
from langchain_core.messages import AIMessage
|
| 5 |
+
from agent import app
|
| 6 |
+
from datetime import datetime
|
| 7 |
+
|
| 8 |
+
api = FastAPI(
|
| 9 |
+
title="Sarvam AI Agent Server (ReAct)",
|
| 10 |
+
description="An API for interacting with the LangGraph pre-built ReAct agent.",
|
| 11 |
+
version="2.0.0"
|
| 12 |
+
)
|
| 13 |
+
|
| 14 |
+
class QueryRequest(BaseModel):
|
| 15 |
+
query: str
|
| 16 |
+
session_id: str
|
| 17 |
+
|
| 18 |
+
sessions: dict[str, List[Tuple[str, str]]] = {}
|
| 19 |
+
|
| 20 |
+
def get_current_date_context():
|
| 21 |
+
"""Gets the current date and formats it as a string for the AI."""
|
| 22 |
+
now = datetime.now()
|
| 23 |
+
return f"For context, today's date is {now.strftime('%A, %B %d, %Y')}."
|
| 24 |
+
|
| 25 |
+
@api.post("/invoke")
|
| 26 |
+
def invoke_agent(request: QueryRequest):
|
| 27 |
+
"""
|
| 28 |
+
Main endpoint to run the agent. Manages conversation history.
|
| 29 |
+
"""
|
| 30 |
+
current_messages = sessions.get(request.session_id, [])
|
| 31 |
+
|
| 32 |
+
if not current_messages:
|
| 33 |
+
query_with_context = f"{request.query} ({get_current_date_context()})"
|
| 34 |
+
user_message = ("user", query_with_context)
|
| 35 |
+
else:
|
| 36 |
+
user_message = ("user", request.query)
|
| 37 |
+
|
| 38 |
+
current_messages.append(user_message)
|
| 39 |
+
|
| 40 |
+
inputs = {"messages": current_messages}
|
| 41 |
+
|
| 42 |
+
final_response_content = ""
|
| 43 |
+
print("\n--- AGENT STREAM STARTED ---")
|
| 44 |
+
for event in app.stream(inputs, stream_mode="values"):
|
| 45 |
+
messages = event.get('messages', [])
|
| 46 |
+
if messages:
|
| 47 |
+
final_message = messages[-1]
|
| 48 |
+
|
| 49 |
+
# --- DEBUG PRINT STATEMENT ---
|
| 50 |
+
# This will show us every step the agent takes.
|
| 51 |
+
print(f"DEBUG: {final_message}\n")
|
| 52 |
+
|
| 53 |
+
if isinstance(final_message, AIMessage) and not final_message.tool_calls:
|
| 54 |
+
final_response_content = final_message.content
|
| 55 |
+
|
| 56 |
+
print("--- AGENT STREAM ENDED ---\n")
|
| 57 |
+
current_messages.append(("assistant", final_response_content))
|
| 58 |
+
sessions[request.session_id] = current_messages
|
| 59 |
+
|
| 60 |
+
return {"response": final_response_content}
|
prompts.py
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
SYSTEM_PROMPT = """You are an expert astrological and calendar assistant. Your primary function is to use the provided tools to answer user queries accurately.
|
| 2 |
+
|
| 3 |
+
**Core Directives:**
|
| 4 |
+
1. **Tool First:** You MUST use the provided tools to find information. Never answer from your own general knowledge. If the tools do not provide an answer, state that the information could not be found.
|
| 5 |
+
2. **Language Match:** You MUST respond in the exact language of the user's query. You are proficient in English (EN), Hindi (HI), Bengali (BN), Gujarati (GU), Tamil (TA), Telugu (TE), Kannada (KN), Malayalam (ML), Marathi (MR), Oriya (OR), and Panjabi (PA).
|
| 6 |
+
3. **Interpret, Don't Dump:** Your job is to interpret the JSON data returned by the tools and present it to the user in a clear, well-formatted, and human-readable way. Do not just output the raw JSON.
|
| 7 |
+
|
| 8 |
+
---
|
| 9 |
+
|
| 10 |
+
**Tool Usage and Data Interpretation Guide:**
|
| 11 |
+
|
| 12 |
+
**1. `get_horoscope`**
|
| 13 |
+
- **When to Use:** Use this tool when a user asks for a horoscope for any zodiac sign (e.g., Aries, Leo, Gemini).
|
| 14 |
+
- **Data Interpretation:** The tool returns a JSON object with keys like `prediction`, `monetary_gains`, `love_life`, `health`, `lucky_number`, and `lucky_color`. Format your response using clear headings for each of these categories. For example:
|
| 15 |
+
"Here is the horoscope for [Sign]:
|
| 16 |
+
**Prediction:** [prediction text]
|
| 17 |
+
**Love Life:** [love life text]
|
| 18 |
+
**Lucky Number:** [number]"
|
| 19 |
+
|
| 20 |
+
**2. `get_date_panchang`**
|
| 21 |
+
- **When to Use:** Use this tool when a user asks for the "Panchang," "Panchangam," or detailed daily astrological details for a specific date.
|
| 22 |
+
- **Data Interpretation:** This tool returns a very large JSON object. **Do not dump the entire object.**
|
| 23 |
+
- If the user asks for the general Panchang, summarize the most important elements: **Sunrise, Sunset, Tithi, Nakshatra, Yoga, and Karana**.
|
| 24 |
+
- If the user asks for a specific detail (e.g., "What is Rahu Kalam today?"), find that specific key in the JSON (`Rahu Kalam`) and provide only that information.
|
| 25 |
+
|
| 26 |
+
**3. `get_holidays`**
|
| 27 |
+
- **When to Use:** Use this tool for general queries about holidays within a specific **year**. This tool provides a list of Hindu, Islamic, Christian, and Government holidays.
|
| 28 |
+
- **Data Interpretation:** Present the holidays in a clean list format. You can group them by month if the list is long.
|
| 29 |
+
|
| 30 |
+
**4. `get_monthly_festivals`**
|
| 31 |
+
- **When to Use:** Prefer this tool when a user asks for festivals in a specific **month**. It provides more detail than `get_holidays`.
|
| 32 |
+
- **Data Interpretation:** Format the response as a list of festivals for that month, including the date for each.
|
| 33 |
+
|
| 34 |
+
---
|
| 35 |
+
|
| 36 |
+
**Final Response Style:**
|
| 37 |
+
Your final answer to the user should always be friendly, well-formatted, and directly address their question using only the data you retrieved from the tools.
|
| 38 |
+
"""
|
requirements.txt
ADDED
|
Binary file (3.03 kB). View file
|
|
|
tools.py
ADDED
|
@@ -0,0 +1,168 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import datetime
|
| 2 |
+
import json
|
| 3 |
+
import requests
|
| 4 |
+
import pytz
|
| 5 |
+
from dateutil import parser
|
| 6 |
+
from typing import Optional, Literal
|
| 7 |
+
from langchain.tools import tool
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
@tool
|
| 11 |
+
def get_horoscope(sign: str, date: str = None, language: str = "EN") -> str:
|
| 12 |
+
"""
|
| 13 |
+
Fetches the horoscope for a given zodiac sign and date from the ExaWeb API.
|
| 14 |
+
Defaults to today if no date is provided.
|
| 15 |
+
|
| 16 |
+
Args:
|
| 17 |
+
sign: Zodiac sign (e.g., Aries, Taurus, Gemini).
|
| 18 |
+
date: Date in any recognizable format (optional).
|
| 19 |
+
language: Language code (e.g., 'EN' for English, 'HI' for Hindi).
|
| 20 |
+
"""
|
| 21 |
+
try:
|
| 22 |
+
if date:
|
| 23 |
+
date_obj = parser.parse(date)
|
| 24 |
+
else:
|
| 25 |
+
date_obj = datetime.datetime.now()
|
| 26 |
+
|
| 27 |
+
formatted_date = date_obj.strftime("%d-%m-%Y")
|
| 28 |
+
|
| 29 |
+
params = {
|
| 30 |
+
"rashi": sign.upper(),
|
| 31 |
+
"language": language,
|
| 32 |
+
"day": formatted_date
|
| 33 |
+
}
|
| 34 |
+
url = "https://api.exaweb.in:3004/api/rashi"
|
| 35 |
+
|
| 36 |
+
response = requests.get(url, params=params)
|
| 37 |
+
response.raise_for_status() # Raise an exception for HTTP errors
|
| 38 |
+
|
| 39 |
+
data = response.json()
|
| 40 |
+
sign_data = data.get(sign.upper())
|
| 41 |
+
|
| 42 |
+
if sign_data:
|
| 43 |
+
return json.dumps(sign_data)
|
| 44 |
+
|
| 45 |
+
return f"INFO: No horoscope found for sign: {sign}"
|
| 46 |
+
|
| 47 |
+
except requests.exceptions.RequestException as e:
|
| 48 |
+
return f"ERROR: [get_horoscope]: Network error while fetching horoscope: {e}"
|
| 49 |
+
except Exception as e:
|
| 50 |
+
return f"ERROR: [get_horoscope]: An unexpected error occurred: {str(e)}"
|
| 51 |
+
|
| 52 |
+
|
| 53 |
+
|
| 54 |
+
@tool
|
| 55 |
+
def get_date_panchang(date: str = None, data_language: str = "EN") -> str:
|
| 56 |
+
"""
|
| 57 |
+
Fetches the Panchang data for a given date.
|
| 58 |
+
If the user does not provide a date, use today's real date.
|
| 59 |
+
|
| 60 |
+
Args:
|
| 61 |
+
date: Date in any format (optional).
|
| 62 |
+
data_language: Language of the Panchang data (e.g., 'EN' for English, 'HI' for Hindi).
|
| 63 |
+
"""
|
| 64 |
+
try:
|
| 65 |
+
if not date:
|
| 66 |
+
now = datetime.datetime.now()
|
| 67 |
+
else:
|
| 68 |
+
now = parser.parse(date)
|
| 69 |
+
|
| 70 |
+
api_date = now.strftime("%d/%m/%y")
|
| 71 |
+
|
| 72 |
+
url = (
|
| 73 |
+
f"https://api.exaweb.in:3004/api/panchang/daily?"
|
| 74 |
+
f"date={api_date}&app_language=EN&data_language={data_language}"
|
| 75 |
+
)
|
| 76 |
+
headers = {"api_key": "anvl_bharat_cal123"}
|
| 77 |
+
|
| 78 |
+
response = requests.get(url, headers=headers)
|
| 79 |
+
response.raise_for_status()
|
| 80 |
+
data = response.json()
|
| 81 |
+
|
| 82 |
+
if not isinstance(data, dict) or not data:
|
| 83 |
+
return "ERROR: [get_date_panchang]: Received empty or invalid data from API."
|
| 84 |
+
|
| 85 |
+
# Simplified formatting for clarity
|
| 86 |
+
return json.dumps(data)
|
| 87 |
+
|
| 88 |
+
except requests.exceptions.RequestException as e:
|
| 89 |
+
return f"ERROR: [get_date_panchang]: Network error while fetching Panchang: {e}"
|
| 90 |
+
except Exception as e:
|
| 91 |
+
return f"ERROR: [get_date_panchang]: An unexpected error occurred: {str(e)}"
|
| 92 |
+
|
| 93 |
+
|
| 94 |
+
|
| 95 |
+
@tool
|
| 96 |
+
def get_holidays(year: int = None, data_language: str = "EN") -> str:
|
| 97 |
+
"""
|
| 98 |
+
Fetches holidays from all categories for a given year from ExaWeb API.
|
| 99 |
+
|
| 100 |
+
Args:
|
| 101 |
+
year: Year (e.g., 2025). Optional — defaults to current year.
|
| 102 |
+
data_language: Data language for holidays (default: "EN").
|
| 103 |
+
"""
|
| 104 |
+
if not year:
|
| 105 |
+
year = datetime.datetime.now().year
|
| 106 |
+
|
| 107 |
+
params = {"data_language": data_language, "year": year}
|
| 108 |
+
headers = {"api_key": "anvl_bharat_cal123"}
|
| 109 |
+
|
| 110 |
+
try:
|
| 111 |
+
response = requests.get(
|
| 112 |
+
"https://api.exaweb.in:3004/api/panchang/holiday",
|
| 113 |
+
params=params,
|
| 114 |
+
headers=headers
|
| 115 |
+
)
|
| 116 |
+
response.raise_for_status()
|
| 117 |
+
data = response.json()
|
| 118 |
+
return json.dumps(data)
|
| 119 |
+
|
| 120 |
+
except requests.exceptions.RequestException as e:
|
| 121 |
+
return f"ERROR: [get_holidays]: Network error fetching holidays: {e}"
|
| 122 |
+
except Exception as e:
|
| 123 |
+
return f"ERROR: [get_holidays]: An unexpected error occurred: {str(e)}"
|
| 124 |
+
|
| 125 |
+
|
| 126 |
+
|
| 127 |
+
@tool
|
| 128 |
+
def get_monthly_festivals(year: Optional[int] = None, month: Optional[str] = None, data_language: str = "EN") -> str:
|
| 129 |
+
"""
|
| 130 |
+
Fetches festival data for a specific month and year from the ExaWeb API.
|
| 131 |
+
|
| 132 |
+
Args:
|
| 133 |
+
year: The year to fetch (e.g., 2025). Defaults to current year.
|
| 134 |
+
month: The full month name to fetch (e.g., "june"). Defaults to current month.
|
| 135 |
+
data_language: The language for the festival names (default: "EN").
|
| 136 |
+
"""
|
| 137 |
+
if not year:
|
| 138 |
+
year = datetime.datetime.now().year
|
| 139 |
+
if not month:
|
| 140 |
+
month = datetime.datetime.now().strftime("%B").lower()
|
| 141 |
+
else:
|
| 142 |
+
month = month.lower()
|
| 143 |
+
|
| 144 |
+
api_url = "https://api.exaweb.in:3004/api/panchang/festival"
|
| 145 |
+
params = {"year": year, "month": month, "data_language": data_language}
|
| 146 |
+
headers = {"api_key": "anvl_bharat_cal123"}
|
| 147 |
+
|
| 148 |
+
try:
|
| 149 |
+
response = requests.get(api_url, params=params, headers=headers)
|
| 150 |
+
response.raise_for_status()
|
| 151 |
+
data = response.json()
|
| 152 |
+
return json.dumps(data)
|
| 153 |
+
|
| 154 |
+
except requests.exceptions.RequestException as e:
|
| 155 |
+
return f"ERROR: [get_monthly_festivals]: Network error while fetching data: {e}"
|
| 156 |
+
except Exception as e:
|
| 157 |
+
return f"ERROR: [get_monthly_festivals]: An unexpected error occurred: {str(e)}"
|
| 158 |
+
|
| 159 |
+
|
| 160 |
+
# List of all tools available in the module
|
| 161 |
+
|
| 162 |
+
all_tools = [
|
| 163 |
+
get_horoscope,
|
| 164 |
+
get_date_panchang,
|
| 165 |
+
get_holidays,
|
| 166 |
+
get_monthly_festivals
|
| 167 |
+
]
|
| 168 |
+
|