File size: 4,015 Bytes
db70198
c65178d
e698d82
db70198
c65178d
 
 
 
0c5e8e3
1ce831d
68eaa27
1ec5b20
b5bc349
6f96801
 
18a32c9
1ec5b20
18a32c9
 
 
 
 
a499b16
 
 
18a32c9
 
 
4ddc82f
a499b16
 
 
 
4ddc82f
7713f97
 
3373c54
e698d82
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60d06b5
e698d82
 
 
 
 
 
 
 
 
60d06b5
0e17e2d
e698d82
 
18a32c9
e698d82
 
db70198
e698d82
 
 
 
 
 
c65178d
e698d82
 
 
 
 
 
 
c65178d
e698d82
 
 
 
 
 
 
c65178d
e698d82
 
 
 
7713f97
e698d82
 
7713f97
0e17e2d
1ec5b20
e698d82
0e17e2d
 
7713f97
0e17e2d
 
 
 
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
import streamlit as st
from langchain.chains.conversational_retrieval.base import ConversationalRetrievalChain
from langchain.chains.retrieval_qa.base import RetrievalQA
from langchain.memory import ConversationBufferMemory
from langchain_community.chat_message_histories.streamlit import (
    StreamlitChatMessageHistory,
)
from langchain_community.chat_models.openai import ChatOpenAI

from calback_handler import PrintRetrievalHandler, StreamHandler
from chat_profile import ChatProfileRoleEnum
from document_retriever import configure_retriever

LLM_MODEL = "gpt-3.5-turbo"

st.set_page_config(
    page_title="InkChatGPT: Chat with Documents",
    page_icon="πŸ“š",
    initial_sidebar_state="collapsed",
    menu_items={
        "Get Help": "https://x.com/vinhnx",
        "Report a bug": "https://github.com/vinhnx/InkChatGPT/issues",
        "About": """InkChatGPT is a simple Retrieval Augmented Generation (RAG) application that allows users to upload PDF documents and engage in a conversational Q&A, with a language model (LLM) based on the content of those documents.
        
        GitHub: https://github.com/vinhnx/InkChatGPT""",
    },
)

# Hide Header
# st.markdown(
#     """<style>.stApp [data-testid="stToolbar"]{display:none;}</style>""",
#     unsafe_allow_html=True,
# )

# Setup memory for contextual conversation
msgs = StreamlitChatMessageHistory()

with st.sidebar:
    with st.container():
        col1, col2 = st.columns([0.2, 0.8])
        with col1:
            st.image(
                "./assets/app_icon.png",
                use_column_width="always",
                output_format="PNG",
            )
        with col2:
            st.header(":books: InkChatGPT")

    # chat_tab,
    documents_tab, settings_tab = st.tabs(
        [
            # "Chat",
            "Documents",
            "Settings",
        ]
    )
    with settings_tab:
        openai_api_key = st.text_input("OpenAI API Key", type="password")
        if len(msgs.messages) == 0 or st.button("Clear message history"):
            msgs.clear()
            msgs.add_ai_message("""
            Hi, your uploaded document(s) had been analyzed. 
            
            Feel free to ask me any questions. For example: you can start by asking me `'What is this book about?` or `Tell me about the content of this book!`' 
            """)

    with documents_tab:
        uploaded_files = st.file_uploader(
            label="Select files",
            type=["pdf", "txt", "docx"],
            accept_multiple_files=True,
            disabled=(not openai_api_key),
        )

if not openai_api_key:
    st.info("πŸ”‘ Please Add your **OpenAI API key** on the `Settings` to continue.")

if uploaded_files:
    result_retriever = configure_retriever(uploaded_files)

    if result_retriever is not None:
        memory = ConversationBufferMemory(
            memory_key="chat_history",
            chat_memory=msgs,
            return_messages=True,
        )

        # Setup LLM and QA chain
        llm = ChatOpenAI(
            model=LLM_MODEL,
            api_key=openai_api_key,
            temperature=0,
            streaming=True,
        )

        chain = ConversationalRetrievalChain.from_llm(
            llm,
            retriever=result_retriever,
            memory=memory,
            verbose=False,
            max_tokens_limit=4000,
        )

        avatars = {
            ChatProfileRoleEnum.HUMAN: "user",
            ChatProfileRoleEnum.AI: "assistant",
        }

        for msg in msgs.messages:
            st.chat_message(avatars[msg.type]).write(msg.content)

if user_query := st.chat_input(
    placeholder="Ask me anything!",
    disabled=(not openai_api_key and not result_retriever),
):
    st.chat_message("user").write(user_query)

    with st.chat_message("assistant"):
        retrieval_handler = PrintRetrievalHandler(st.empty())
        stream_handler = StreamHandler(st.empty())
        response = chain.run(user_query, callbacks=[retrieval_handler, stream_handler])