| import pandas as pd |
| import numpy as np |
| from langchain_core.prompts import ChatPromptTemplate |
| from langchain.agents import AgentExecutor, create_openai_functions_agent |
| from langchain.tools import Tool ,StructuredTool |
|
|
| from langchain_google_genai import ChatGoogleGenerativeAI |
| import json |
| from langchain.memory import ConversationBufferMemory |
| from dotenv import load_dotenv |
| from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder |
| import ast |
| import time |
| |
| import datetime |
| import os.path |
| from google.auth.transport.requests import Request |
| from google_auth_oauthlib.flow import InstalledAppFlow |
| from google.oauth2.credentials import Credentials |
| from googleapiclient.discovery import build |
|
|
| import os |
| load_dotenv() |
| GOOGLE_API_KEY = os.getenv('GOOGLE_API_KEY') |
|
|
|
|
|
|
| |
| |
| |
| |
| |
| |
| |
|
|
|
|
| |
| |
| |
| |
| |
| |
| |
| |
|
|
|
|
|
|
| |
|
|
| |
| |
|
|
| |
| |
| |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| |
| |
| |
|
|
| |
| |
|
|
|
|
| def get_calendar_service(): |
| """ |
| Connects to the Google Calendar API. |
| |
| IMPORTANT FOR DEPLOYMENT: |
| This function uses an interactive OAuth flow that will not work in a Docker container. |
| To deploy this, you must: |
| 1. Run the application locally ONCE to complete the Google login flow. |
| 2. This will create a `token.json` file. |
| 3. Ensure that BOTH `credentials.json` and the generated `token.json` are included |
| in your Docker image or Hugging Face Space so the agent can authenticate non-interactively. |
| """ |
| creds = None |
| SCOPES = ['https://www.googleapis.com/auth/calendar'] |
|
|
| |
| if os.path.exists('token.json'): |
| creds = Credentials.from_authorized_user_file('token.json', SCOPES) |
|
|
| |
| if not creds or not creds.valid: |
| if creds and creds.expired and creds.refresh_token: |
| creds.refresh(Request()) |
| else: |
| flow = InstalledAppFlow.from_client_secrets_file( |
| 'credentials.json', SCOPES |
| ) |
| creds = flow.run_local_server(port=0) |
|
|
| |
| with open('token.json', 'w') as token: |
| token.write(creds.to_json()) |
|
|
| return build('calendar', 'v3', credentials=creds) |
|
|
| |
|
|
|
|
|
|
| def check_slots(details)-> None: |
| print(f"inside check_slots") |
| print(f"Type of details {type(details)}") |
| print(f"details {details}") |
| if type(details) is str: |
| details = ast.literal_eval(details) |
| print(f"Type of details {type(details)}") |
| print(f"Here is details {details}") |
| service = get_calendar_service() |
| print(f"service {service}") |
| calendar_id='primary' |
| body = { |
| "timeMin": details['start_time'], |
| "timeMax": details['end_time'], |
| "items": [{"id": calendar_id}] |
| } |
| print(f"Here in check_slots {body}") |
| try: |
| events_result = service.freebusy().query(body=body).execute() |
| busy_times = events_result['calendars'][calendar_id]['busy'] |
| return busy_times |
| except Exception as e: |
| return f"Faield due to {e}" |
| |
|
|
| def add_meet(details: dict, summary: str)-> None: |
| if type(details) is str: |
| details = ast.literal_eval(details) |
| start_time = details['start_time'] |
| end_time = details['end_time'] |
| attendees = details['attendees'] |
| service = get_calendar_service() |
| print(f"here is detais in add_meet {details}") |
| print(f"Here is attendees {attendees}") |
| event = { |
| 'summary': summary, |
| 'description': f"Meeting scheduled with a user.", |
| 'start':{ |
| 'dateTime':start_time, |
| 'timeZone':'Asia/Kolkata', |
| }, |
| 'end':{ |
| 'dateTime': end_time, |
| 'timeZone':'Asia/Kolkata' |
| }, |
| 'attendees':[ |
| {'email': attendee} for attendee in attendees |
| ] |
| } |
| print(f"here is event in add_time {event}") |
| event = service.events().insert(calendarId='primary',body=event,sendUpdates='all').execute() |
| print(f"After event {event}") |
| return f"Event successfully booked {event.get('htmlLink')}" |
|
|
| |
| |
|
|
| |
| |
|
|
| |
| |
|
|
|
|
| memory = ConversationBufferMemory(memory_key="chat_history",return_messages=True) |
|
|
| system_prompt = ''' |
| You are helpful Ai Assistant, help the user to Schedule a meeting with 'Harsimran Singh'. You working with more than 5+ Years of Experience. Following is your task you need to done professionally, step by step and with understanding :- |
| - Great the user with short welcome message. |
| - You ask to user when you want to schedule a meeting Day or Date with how much time meeting will goes it needs to ask time how much for meeting needed. |
| - If user tell about 20 Minutes then find 30 minutes slot from Harsimran Sing Calender or 35 minutes than 45 minutes. |
| - Provide them best 3 Timings, if timing are not available than you can provide alternative day to the user. |
| - Collect the name, email, timing to the user if user tell only timing not name & mail then collect the mail and name don't book without these details. |
| - After succesfully scheduled the meeting great the user with Thank message. |
| - You need to anlayse the date by your self here is current date and time. |
| - After successfully booked the meet, great the user with Thanks message. |
| - Don't use too large sentences, try to keep short messages. |
| - You can use the emojis also and some time be casual. |
| - After collecting the mail confirm the mail id and slot timeing before booking a slot. |
| Tools that you need to use during schedule the meeting:- |
| - {{check_slots}} - Check the slots of the Harsimran Singh |
| - {{add_meet_calender}} - Schedule the meeting with Harsimran Singh after getting Name, mail and timing. |
| |
| Data you need to pass between in Tools:- |
| - {{check_slots}} -> use variable "details" (in dict) with 'start_time' and 'end_time' keys. |
| ->> example:- |
| {{'start_time': '2025-06-22T17:00:00+05:30', 'end_time': '2025-06-22T17:30:00+05:30'}} |
| - {{add_meet}} -> use "details" (in dict) with 'start_time', 'end_time', and 'attendees' keys. |
| -> use "summary" (str, up to 50 words). |
| ->> Example - |
| details={{'start_time': '2025-06-22T17:00:00+05:30', 'end_time': '2025-06-22T17:30:00+05:30', 'attendees': ['harsimransd726@gmail.com']}}, summary='Meeting with Harsimran Singh' |
| |
| - if check_slots return empty then it means Harsimran is Avaliable. |
| Use this Date_Time Format:- '2025-06-17T14:00:00+05:30' |
| |
| |
| ''' |
|
|
| check_slots_calender = StructuredTool.from_function( |
| name="check_slots_available", |
| description="Check the availability in Google Calender, pass the dictionary varialbe 'detials' containing 'start_time' and 'end_time' keys.", |
| func=check_slots, |
| ) |
|
|
| add_meet_calender = StructuredTool.from_function( |
| name="add_meeting_calender", |
| description="Book or schedule the meeting with user. Requires 'details' dictionary and a 'summary' string.", |
| func=add_meet, |
| ) |
|
|
|
|
| llm = ChatGoogleGenerativeAI(model='gemini-2.5-flash', |
| api_key=GOOGLE_API_KEY, |
| temperature=0.8) |
|
|
|
|
| prompt = ChatPromptTemplate.from_messages( |
| [ |
| ( |
| "system", |
| system_prompt |
| ), |
| ("placeholder","{chat_history}"), |
| ("human","{input}"), |
| MessagesPlaceholder(variable_name="agent_scratchpad"), |
| ] |
| ) |
|
|
|
|
| Tools = [check_slots_calender,add_meet_calender] |
|
|
| agent = create_openai_functions_agent(llm=llm,tools=Tools,prompt=prompt) |
| conversation = AgentExecutor(agent=agent,tools=Tools,memory=memory,verbose=True) |
|
|
| async def user_input(query: str): |
| |
| date_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()) |
| query = f"Current time:- {date_time}" + f"user said: {query}" |
| print(f"the query is {query}") |
| if query: |
| try: |
| print(f"before invoking") |
| response = await conversation.ainvoke({"input":query}) |
| print(f"Here is the final response {response['output']}") |
| return response['output'] |
| except Exception as e: |
| return f"SOrry please try again later {e}" |
|
|