File size: 5,387 Bytes
b6054db
 
 
 
 
 
 
 
 
 
d47c7a8
 
 
b6054db
d47c7a8
 
 
 
b6054db
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
d47c7a8
b6054db
d47c7a8
b6054db
d47c7a8
 
 
 
 
b6054db
d47c7a8
 
b6054db
 
 
 
 
 
 
 
 
d47c7a8
 
b6054db
d47c7a8
b6054db
d47c7a8
b6054db
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1e26132
b6054db
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
import chainlit as cl
import pandas as pd
import os
from dotenv import load_dotenv, find_dotenv
from agents import Agent, Runner, AsyncOpenAI, OpenAIChatCompletionsModel ,function_tool
from agents.run import RunConfig
from openai.types.responses import ResponseTextDeltaEvent



# @cl.on_message
# async def main(message: cl.Message):
#     # Your custom logic goes here...

#     # Send a response back to the user
#     await cl.Message(
#         content=f"Received: {message.content}",
#     ).send()

CSV_PATH = "availablity.csv"

def load_data():
    return pd.read_csv(CSV_PATH)

def save_data(df):
    df.to_csv(CSV_PATH, index=False)

# Get availability for a given date
@function_tool
def get_availability(date: str) -> str:
    """
            Returns a list of available room types for a given date.

        Args:
            date (str): The date to check availability for (format: YYYY-MM-DD).

        Returns:
            str: A formatted string listing available room types and counts,
                or a message indicating no availability or invalid date.

    """
    df = load_data()
    day_rooms = df[df['date'] == date]

    if day_rooms.empty:
        return f"No availability data for {date}."

    available_rooms = day_rooms[day_rooms['available'] > 0]
    if available_rooms.empty:
        return f"No rooms available on {date}."

    result = [f"{row.room_type.title()} ({row.available} available)" for _, row in available_rooms.iterrows()]
    return f"Available rooms on {date}:\n" + "\n".join(result)

# Book a room if available
@function_tool
def book_room(date: str, room_type: str, guests: int, num_rooms: int = 1) -> str:
    """
    Attempts to book a specified number of rooms of the given type on a date.

    Args:
        date (str): The booking date (format: YYYY-MM-DD).
        room_type (str): The type of room to book (e.g., 'single', 'double', 'suite').
        guests (int): Number of guests for the booking.
        num_rooms (int, optional): Number of rooms to book. Defaults to 1.

    Returns:
        str: A confirmation message if booking is successful, or an error message.
    """
    df = load_data()
    match = (df['date'] == date) & (df['room_type'].str.lower() == room_type.lower())
    room_row = df[match]

    if room_row.empty:
        return f"No {room_type} room available on {date}."

    idx = room_row.index[0]
    if df.at[idx, 'available'] >= num_rooms:
        df.at[idx, 'available'] -= num_rooms
        save_data(df)
        return f"✅ Booked {num_rooms} {room_type.title()} room(s) for {guests} guest(s) on {date}."
    else:
        return f"❌ Only {df.at[idx, 'available']} {room_type.title()} rooms left on {date}."

load_dotenv(find_dotenv())
api_key = os.getenv('OpenAI_api_key')

external_client = AsyncOpenAI(
    api_key=api_key,
    base_url="https://api.aimlapi.com/v1",
)

model = OpenAIChatCompletionsModel(
    model="gpt-4",
    openai_client=external_client
)

config = RunConfig(
    model=model,
    model_provider=external_client,
    tracing_disabled=True
)

agent: Agent = Agent(
    name="Receptionist", 
    instructions="You are a helpful hotel receptionist. You can help with booking rooms, checking availability regarding specific date user provides, and answering questions about the hotel.",
    tools=[get_availability, book_room], 
    model=model
    )


@cl.on_chat_start
async def on_chat_start():
    cl.user_session.set("history", [])
    await cl.Message("Hi! This AI powered Hotel Receptionist which can book hotel room, answer common queries and check hotel rooms availiblity from hotel's database for you!!").send()

@cl.on_message
async def handle(message: cl.Message):
    history = cl.user_session.get("history")

    history.append({
        "role": "user",
        "content": message.content
    })

    msg = cl.Message(content="")

    # Format history as a string to avoid passing raw dictionaries
    def format_history(history):
        formatted = []
        for entry in history:
            role = entry["role"].title()
            content = entry["content"]
            formatted.append(f"{role}: {content}")
        return "\n".join(formatted)

    result = Runner.run_streamed(agent, format_history(history), run_config=config)
    async for event in result.stream_events():
        if event.type == "raw_response_event" and isinstance(event.data, ResponseTextDeltaEvent):
            response = event.data.delta
            if isinstance(response, str):
                await msg.stream_token(response)
            elif isinstance(response, dict) and "content" in response:
                await msg.stream_token(response["content"])
            else:
                print(f"Unexpected response format: {response}")
        
        elif event.type == "final_response":
            if hasattr(event.data, "content") and isinstance(event.data.content, str):
                await msg.stream_token(event.data.content)
            elif isinstance(event.data, dict) and "content" in event.data:
                await msg.stream_token(event.data["content"])
            else:
                print(f"Unexpected final response format: {event.data}")

    # Store only the content in history
    history.append({
        "role": "receptionist",
        "content": msg.content
    })
    cl.user_session.set("history", history)

    await msg.update()