File size: 7,781 Bytes
12654ba
747720a
 
12654ba
 
 
 
 
 
 
 
 
 
 
 
 
 
 
747720a
 
 
 
 
 
 
12654ba
 
78b9b84
12654ba
 
74fa98d
 
 
 
12654ba
490ca3b
 
74fa98d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
efdd6c6
 
 
12654ba
 
3951ea6
12654ba
 
 
 
f79a832
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
747720a
12654ba
 
 
747720a
12654ba
 
 
 
 
 
 
 
 
a77a669
 
 
12654ba
 
 
 
 
 
 
 
 
 
 
 
 
 
747720a
 
12654ba
 
 
 
 
 
 
 
 
 
 
fc84509
12654ba
747720a
12654ba
 
f79a832
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2cd826a
f79a832
 
 
 
 
 
 
 
2cd826a
f79a832
fc84509
f79a832
 
fc84509
12654ba
a77a669
 
 
 
 
 
 
 
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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# ===========================================
# title: daysoff-assistant-API-v2
# file: app.py
# ===========================================

import json
import asyncio
import os
import re
import requests
from dotenv import load_dotenv
import chainlit as cl
from langchain import hub
from langchain_openai import OpenAI
from langchain.chains import LLMChain
from langchain_core.prompts import PromptTemplate
from langchain.memory.buffer import ConversationBufferMemory

# ---------------------------------------------------for backend looks, example file:----------------------------------

#with open('/usr/local/lib/python3.10/site-packages/transformers/utils/chat_template_utils.py', 'r') as file:
    #content = file.read()
    #print("base.py:", content)
# ------------------------------------------------------the end--------------------------------------------------------

load_dotenv()
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
auth_token = os.environ.get("DAYSOFF_API_TOKEN")

API_URL = "https://aivisions.no/data/daysoff/api/v1/booking/"
# and help users retrieve booking information associated with their bookingnr
# Provide a conversational answer.
# This way you directly address the user's question in a manner that reflects the professionalism and warmth
# of a customer support representative (female).
daysoff_assistant_template = """
You are a customer support assistant for Daysoff kundeservice and help users retrieve their booking information based on a bookingnr they give you.
It is important that you use the term "bookingnr".
Users may reference their bookingnr in different ways.
# examples
Norwegian Terms:
- booking
- bookingnr
- bestillingsnummer
- bookingen
- ordrenummer
- bookingreferanse
- bestilling
- booket
English Terms:
- reservation
- reservation number
- order number
- booking ID
Polish Terms:
- rezerwacji
- rezerwacja
- identyfikacyjny pล‚atnoล›ci

If there is no booking information available for a booking ID, just say so and politely suggest they contact **[email protected]**
to enquire further.

Maintain a conversational and professional tone, **reflecting the warmth of
a female customer support representative archetype.** 
By default, you answer in **Norwegian**.

Chat History: {chat_history}
Question: {question}
Answer:
"""
daysoff_assistant_prompt = PromptTemplate(
    input_variables=["chat_history", "question"],
    template=daysoff_assistant_template,
)


# =============================================================================================================
class APIConnectionError(Exception):
    """Raised when API connection fails"""
    pass

class APIResponseError(Exception):
    """Raised when API returns invalid response"""
    pass

class BookingNotFoundError(Exception):
    """Raised when booking ID is not found"""
    pass
# =============================================================================================================

#async def async_post_request(url, headers, data):
    #return await asyncio.to_thread(requests.post, url, headers=headers, json=data)

# =============================================================================================================
async def async_post_request(url, headers, data):
    try:
        response = await asyncio.to_thread(requests.post, url, headers=headers, json=data)
        response.raise_for_status()
        return response
    except requests.ConnectionError:
        raise APIConnectionError("Failed to connect to booking service")
    except requests.Timeout:
        raise APIConnectionError("Request timed out")
    except requests.RequestException as e:
        raise APIResponseError(f"API request failed: {str(e)}")
# =============================================================================================================

@cl.on_chat_start
def setup_multiple_chains():
    llm = OpenAI(
        model="gpt-3.5-turbo-instruct",
        temperature=0.7,
        openai_api_key=OPENAI_API_KEY,
        max_tokens=2048,
        top_p=0.9,
        frequency_penalty=0.1,
        presence_penalty=0.1,
    )

    conversation_memory = ConversationBufferMemory(
        memory_key="chat_history",
        max_len=30,
        return_messages=True
    )

    llm_chain = LLMChain(
        llm=llm,
        prompt=daysoff_assistant_prompt,
        memory=conversation_memory,
    )

    cl.user_session.set("llm_chain", llm_chain)

@cl.on_message
async def handle_message(message: cl.Message):
    user_message = message.content
    llm_chain = cl.user_session.get("llm_chain")

    booking_pattern = r'\b[A-Z]{6}\d{6}\b'
    match = re.search(booking_pattern, user_message)

    if match:
        bestillingskode = match.group()
        headers = {
            "Authorization": auth_token,
            "Content-Type": "application/json"
        }
        payload = {"booking_id": bestillingskode}

        try:
            # --async POST request
            response = await async_post_request(API_URL, headers, payload)
            response.raise_for_status()
            booking_data = response.json()

            if not booking_data:
                raise BookingNotFoundError("No booking data returned")
            
            if "error" in booking_data:
                raise APIResponseError(booking_data["error"])

            # --markdown_table
            table = (
                "| ๐‘ญ๐’Š๐’†๐’๐’…      | ๐—œ๐—ป๐—ณ๐—ผ                |\n"
                "|:-----------|:---------------------|\n"
                f"| ๐™ฑ๐šŽ๐šœ๐š๐š’๐š•๐š•๐š’๐š—๐š๐šœ๐š”๐š˜๐š๐šŽ | {booking_data.get('booking_id', 'N/A')} |\n"
                f"| ๐™๐™ช๐™ก๐™ก ๐™‰๐™–๐™ข๐™š  | {booking_data.get('full_name', 'N/A')} |\n"
                f"| ๐˜ผ๐™ข๐™ค๐™ช๐™ฃ๐™ฉ     | {booking_data.get('amount', 0)} kr |\n"
                f"| ๐˜พ๐™๐™š๐™˜๐™ -๐™ž๐™ฃ   | {booking_data.get('checkin', 'N/A')} |\n"
                f"| ๐˜พ๐™๐™š๐™˜๐™ -๐™ค๐™ช๐™ฉ  | {booking_data.get('checkout', 'N/A')} |\n"
                f"| ๐˜ผ๐™™๐™™๐™ง๐™š๐™จ๐™จ    | {booking_data.get('address', 'N/A')} |\n"
                f"| ๐™๐™จ๐™š๐™ง ๐™„๐˜ฟ    | {booking_data.get('user_id', 0)} |\n"
                f"| ๐™„๐™ฃ๐™›๐™ค ๐™๐™š๐™ญ๐™ฉ  | {booking_data.get('infotext', 'N/A')} |\n"
                f"| ๐™„๐™ฃ๐™˜๐™ก๐™ช๐™™๐™š๐™™   | {booking_data.get('included', 'N/A')} |"
            )

            combined_message = f"### Informasjon om booking:\n\n{table}"
            await cl.Message(content=combined_message).send()

        except (APIConnectionError, APIResponseError, BookingNotFoundError) as e:
            error_messages = {
                APIConnectionError: "Kunne ikke koble til bookingsystemet. Prรธv igjen senere.",
                APIResponseError: "Det oppstod en feil ved henting av bookingdata.",
                BookingNotFoundError: "Ingen booking funnet med denne koden."
            }
            await cl.Message(content=f"โŒ {error_messages[type(e)]}\n\nPrรธv igjen, kanskje du feilstavet eller glemte ett siffer?\n\nHvis du ser denne feilmedlingen gjentatte ganger, foreslรฅr jeg at du kontakt [email protected] for assistanse.").send()
            return None
        except requests.exceptions.RequestException as e:
            await cl.Message(content="En uventet feil oppstod. Vennligst kontakt [email protected]").send()
            return None

    else:
        try:
            response = await llm_chain.ainvoke({
                "question": user_message,
                "chat_history": ""
            }, callbacks=[cl.AsyncLangchainCallbackHandler()])
            await cl.Message(content=response["text"]).send()
        except Exception as e:
            await cl.Message(content=f"Error: {str(e)}").send()