File size: 5,443 Bytes
ae58eea
 
95ed623
7cf74a5
7791c9a
95112bf
40695ca
95ed623
40695ca
a3e0cb3
a426480
a3e0cb3
40695ca
 
 
7791c9a
 
 
 
 
95112bf
5d6e27a
95112bf
 
 
 
95ed623
95112bf
7791c9a
95112bf
 
 
 
 
95ed623
95112bf
7791c9a
 
95112bf
 
 
95ed623
95112bf
 
 
 
7791c9a
 
 
a426480
95ed623
95112bf
7791c9a
95112bf
 
95ed623
7791c9a
 
 
 
95ed623
7791c9a
 
 
95ed623
7791c9a
 
 
 
 
 
 
 
95112bf
7791c9a
95ed623
7791c9a
 
95112bf
95ed623
95112bf
95ed623
 
 
7791c9a
a3e0cb3
 
95ed623
95112bf
a3e0cb3
95ed623
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95112bf
2131100
 
95ed623
 
 
 
 
 
 
 
 
 
7791c9a
 
95112bf
7791c9a
95112bf
 
 
95ed623
7791c9a
 
95ed623
079ade3
95ed623
 
7791c9a
 
 
 
95ed623
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import os
os.environ["STREAMLIT_HOME"] = "/tmp/.streamlit"

import streamlit as st
from chat_langraph import system, workflow, HumanMessage, AIMessage, get_all_chat_ids, ToolMessage
import uuid
import base64
import io

st.set_page_config(layout="wide")
st.title("My Chatbot")

TEMP_DIR = "/tmp"
os.makedirs(TEMP_DIR, exist_ok=True)

def set_title(messages):
    if messages:
        title = "New Chat"
        st.session_state.chat_dict[st.session_state.current_chat_id] = title

def set_config():
    return {"configurable": {"thread_id": st.session_state.current_chat_id}}

def load_session_state():
    if "chats" not in st.session_state:
        st.session_state.chats = get_all_chat_ids()

    if "current_chat_id" not in st.session_state:
        if len(st.session_state.chats) > 0:
            st.session_state.current_chat_id = st.session_state.chats[-1]
        else:
            new_id = str(uuid.uuid4())
            st.session_state.chats.append(new_id)
            st.session_state.current_chat_id = new_id

    if "chat_dict" not in st.session_state:
        st.session_state.chat_dict = {}

def render_sidebar():
    with st.sidebar:
        st.title("Chats")

        if st.button("โž• New Chat"):
            new_id = str(uuid.uuid4())
            st.session_state.chats.append(new_id)
            st.session_state.current_chat_id = new_id
            config = {"configurable": {"thread_id": new_id}}
            workflow.update_state(config, {"messages": [system]})
            st.session_state.chat_dict[new_id] = "New Chat"
            st.rerun()

        for chat_id in st.session_state.chats:
            if st.button(st.session_state.chat_dict.get(chat_id, "New Chat"), key=chat_id):
                st.session_state.current_chat_id = chat_id

        st.markdown("---")

def create_download_link(file_path: str, label: str = None) -> str:
    if not os.path.exists(file_path):
        return ""

    try:
        with open(file_path, "rb") as f:
            data = f.read()

        b64 = base64.b64encode(data).decode()
        label = label or f"๐Ÿ“ฅ Download {os.path.basename(file_path)}"
        href = f'<a href="data:file/octet-stream;base64,{b64}" download="{os.path.basename(file_path)}">{label}</a>'
        return href
    except Exception as e:
        return f"Error creating download link: {e}"

def loadchats():
    if "current_chat_id" not in st.session_state:
        return []

    config = {"configurable": {"thread_id": st.session_state.current_chat_id}}
    state = workflow.get_state(config)
    messages = state.values.get("messages", [])

    for message in messages:
        if not message.content:
            continue

        if isinstance(message, HumanMessage):
            with st.chat_message("human"):
                st.write(message.content)

        elif isinstance(message, AIMessage):
            with st.chat_message("assistant"):

                content = message.content
                rendered_text = ""

                if isinstance(content, list):
                    for item in content:
                        if isinstance(item, str):
                            rendered_text += item
                        elif isinstance(item, dict) and "text" in item:
                            rendered_text += item["text"]
                else:
                    rendered_text = str(content)

                st.write(rendered_text)

        elif isinstance(message, ToolMessage):
            with st.chat_message("assistant"):
                st.info("Using Appropriate tool")

                if message.name == "plot_graph" and "Filepath" in message.content:
                    st.image(message.content.split(":")[1], "๐Ÿ“Š")

                if "Filepath" in message.content:
                    st.markdown(
                        create_download_link(message.content.split(":")[1]),
                        unsafe_allow_html=True
                    )

    return messages



load_session_state()
render_sidebar()


if "current_chat_id" in st.session_state:
    loadchats()

    user_input = st.chat_input("Your message:")

    if user_input:
        with st.chat_message("human"):
            st.write(user_input)

        with st.chat_message("assistant"):
            with st.spinner("Assistant is thinking..."):

                response_placeholder = st.empty()
                full_response = ""

                for message, metadata in workflow.stream(
                    {"messages": [system, HumanMessage(user_input)]},
                    config={"configurable": {"thread_id": st.session_state.current_chat_id}},
                    stream_mode="messages",
                ):

                    if isinstance(message, AIMessage):
                        content = message.content

                        if isinstance(content, list):
                            for item in content:
                                if isinstance(item, str):
                                    full_response += item
                                elif isinstance(item, dict) and "text" in item:
                                    full_response += item["text"]
                        else:
                            full_response += str(content)

                    elif isinstance(message, ToolMessage):
                        st.info("Using Appropriate tool")

                    response_placeholder.markdown(full_response + " ")

                st.rerun()