Spaces:
Build error
Build error
| ### title: 010125-daysoff-assistant-api | |
| ### file: app.py | |
| import asyncio | |
| import os | |
| import re | |
| import time | |
| import json | |
| import torch | |
| import logging | |
| from api_docs_mck import api_docs_str | |
| #from daysoff import daysoff_str ## make daysoff.py, put json info in dict. | |
| #from personvernpolicy import personvernpolicy_str ## make personvernpolicy.py, put json info in dict. | |
| import chainlit as cl | |
| from langchain import hub | |
| from langchain.chains import LLMChain, APIChain | |
| from langchain_core.prompts import PromptTemplate | |
| from langchain.memory.buffer import ConversationBufferMemory | |
| from langchain_openai import OpenAI | |
| from langchain_community.llms import HuggingFaceHub | |
| from langchain_huggingface import HuggingFacePipeline | |
| from langchain_huggingface import HuggingFaceEndpoint | |
| from langchain_core.callbacks.streaming_stdout import StreamingStdOutCallbackHandler | |
| #logging.basicConfig(level=logging.DEBUG) | |
| HUGGINGFACE_API_TOKEN = os.environ.get("HUGGINGFACEHUB_API_TOKEN") | |
| #HF_INFERENCE_ENDPOINT = | |
| #BOOKING_ID = re.compile(r'\b[A-Z]{6}\d{6}\b') | |
| BOOKING_KEYWORDS = [ | |
| "booking", | |
| "bestillingsnummer", | |
| "bookingen", | |
| "ordrenummer", | |
| "reservation", | |
| "rezerwacji", | |
| "bookingreferanse", | |
| "rezerwacja", | |
| "booket", | |
| "reservation number", | |
| "bestilling", | |
| "order number", | |
| "booking ID", | |
| "identyfikacyjny płatności" | |
| ] | |
| daysoff_assistant_template = """ | |
| You are a customer support assistant for Daysoff named "Agrippa". Your expertise is in retrieving | |
| booking details for a given booking ID and answering questions about | |
| Daysoff's personvernspolicy and firmahytteordning. You do not provide information outside of this | |
| scope. By default, you respond in Norwegian language. | |
| Chat History: {chat_history} | |
| Question: {question} | |
| Answer: | |
| """ | |
| daysoff_assistant_prompt= PromptTemplate( | |
| input_variables=["chat_history", "question"], | |
| template=daysoff_assistant_template | |
| ) | |
| api_url_template = """ | |
| Given the following API Documentation for Daysoff's official | |
| booking information API: {api_docs} | |
| Your task is to construct the most efficient API URL to answer | |
| the user's question, ensuring the | |
| call is optimized to include only the necessary information. | |
| Question: {question} | |
| API URL: | |
| """ | |
| api_url_prompt = PromptTemplate(input_variables=['api_docs', 'question'], | |
| template=api_url_template) | |
| # (..) If {question} contains an alphanumeric identifier consisting of 6 letters followed by 6 digits (e.g., DAGHNS116478) | |
| api_response_template = """ | |
| With the API Documentation for Daysoff's official API: {api_docs} in mind, | |
| and user question: {question}, and given this API URL: {api_url} for querying, | |
| here is the response from Daysoff's API: {api_response}. | |
| Please provide an summary that directly addresses the user's question, | |
| omitting technical details like response format, and | |
| focusing on delivering the answer with clarity and conciseness, | |
| as if a human customer service agent is providing this information. | |
| Summary: | |
| """ | |
| api_response_prompt = PromptTemplate( | |
| input_variables=['api_docs', 'question', 'api_url', 'api_response'], | |
| template=api_response_template | |
| ) | |
| def setup_multiple_chains(): | |
| llm = OpenAI(model='gpt-3.5-turbo-instruct', | |
| temperature=0.7) | |
| #llm = HuggingFaceEndpoint( | |
| #repo_id="google/gemma-2-2b", #"norallm/normistral-7b-warm-instruct", | |
| #endpoint_url="http://localhost:8010/", | |
| #model="google/gemma-2-2b", | |
| #max_new_tokens=512, | |
| #top_k=10, | |
| #top_p=0.95, | |
| #typical_p=0.95, | |
| #temperature=0.7, | |
| #repetition_penalty=1.03, | |
| #huggingfacehub_api_token=HUGGINGFACE_API_TOKEN, | |
| #task="text-generation" | |
| #) | |
| #llm = HuggingFacePipeline.from_model_id( | |
| #model_id="normistral-7b-warm-instruct", | |
| #task="text-generation", | |
| #pipeline_kwargs={"max_new_tokens": 10}, | |
| #) | |
| conversation_memory = ConversationBufferMemory(memory_key="chat_history", | |
| max_len=200, | |
| return_messages=True, | |
| ) | |
| llm_chain = LLMChain(llm=llm, | |
| prompt=daysoff_assistant_prompt, | |
| memory=conversation_memory | |
| ) | |
| cl.user_session.set("llm_chain", llm_chain) | |
| api_chain = APIChain.from_llm_and_api_docs( | |
| llm=llm, | |
| api_docs=api_docs_str, | |
| api_url_prompt=api_url_prompt, | |
| api_response_prompt=api_response_prompt, | |
| verbose=True, | |
| limit_to_domains=None #["https://670dccd0073307b4ee447f2f.mockapi.io/daysoff/api/V1"] | |
| ) | |
| cl.user_session.set("api_chain", api_chain) | |
| async def handle_message(message: cl.Message): | |
| user_message = message.content.lower() | |
| llm_chain = cl.user_session.get("llm_chain") | |
| api_chain = cl.user_session.get("api_chain") | |
| #if any(keyword in user_message for keyword in ["firmahytteordning","personvernpolicy"]): | |
| #def is_booking_query(user_message): | |
| #match = re.search(r'\b[A-Z]{6}\d{6}\b', user_message) | |
| #return match is not None # --works boolean | |
| #booked = is_booking_query(user_message) | |
| #if booked: | |
| if re.search(r'\b[A-Z]{6}\d{6}\b', user_message): # ex. "EQJLCQ362149" | |
| response = await api_chain.ainvoke(user_message, | |
| callbacks=[cl.AsyncLangchainCallbackHandler()]) | |
| else: | |
| response = await llm_chain.ainvoke(user_message, | |
| callbacks=[cl.AsyncLangchainCallbackHandler()]) | |
| response_key = "output" if "output" in response else "text" | |
| logging.debug({response}) | |
| await cl.Message(response.get(response_key, "")).send() | |
| return message.content | |