File size: 4,014 Bytes
238f0a0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import streamlit as st
import re
from langchain.chat_models import ChatOllama
from langchain.schema import HumanMessage, AIMessage
from langchain.memory import ConversationBufferMemory
from langchain.chains import LLMChain
from langchain.prompts import PromptTemplate

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

model_options = ["llama3.2", "deepseek-r1:1.5b"]
model = st.sidebar.selectbox("Choose a Model", model_options, index=0)

st.sidebar.write("Advanced Settings")
max_history = st.sidebar.number_input("Max History", min_value=1, max_value=10, value=2, step=1)
context_size = st.sidebar.number_input("Max Token", min_value=1024, max_value=2048, value=1024, step=1024)
top_p = st.sidebar.number_input("Top-P", min_value=0.8, max_value=0.95, value=0.8, step=0.01)
top_k = st.sidebar.number_input("Top-K", min_value=20, max_value=50, value=20, step=10)
temperature = st.sidebar.number_input("Temperature", min_value=0.0, max_value=1.0, value=0.5, step=0.1)


def clear_memory():
    st.session_state.memory = ConversationBufferMemory(return_messages=True)

if "prev_context_size" not in st.session_state or st.session_state.prev_context_size != context_size:
    clear_memory()
    st.session_state.prev_context_size = context_size

if "chat_history" not in st.session_state:
    st.session_state.chat_history = []
if "memory" not in st.session_state:
    st.session_state.memory = ConversationBufferMemory(return_message=True)

llm = ChatOllama(model=model, streaming=True, temperature=temperature, top_p=top_p, top_k=top_k)

prompt_template = PromptTemplate(
    input_variable = ["history", "human_input"],
    template="{history}\nJangan tampilkan reasoning internal (<think>...</think>), cukup jawab final saja.\nUser: {human_input}\nAssistant:"
)

chain = LLMChain(llm=llm, prompt=prompt_template, memory=st.session_state.memory)

if "prev_model" not in st.session_state:
    st.session_state.prev_model = model

if st.session_state.prev_model != model:
    st.session_state.chat_history = []
    st.session_state.memory = ConversationBufferMemory(return_messages=True)
    st.session_state.prev_model = model

for msg in st.session_state.chat_history:
    with st.chat_message(msg["role"]):
        st.markdown(msg["content"])

def trim_memory():
    while len(st.session_state.chat_history) > max_history * 2:
        st.session_state.chat_history.pop(0)
        if st.session_state.chat_history:
            st.session_state.chat_history.pop(0)

def clean(text):
    return re.sub(r"<think>.*?</think>", "", text, flags=re.DOTALL).strip()

if prompt := st.chat_input("Say something"):
    with st.chat_message("user"):
        st.markdown(prompt)
    st.session_state.chat_history.append({"role": "user", "content": prompt})
    trim_memory()
    with st.chat_message("assistant"):
        response_container = st.empty()
        full_response = ""
        for chunk in chain.stream({"human_input": prompt}):
            if isinstance(chunk, dict) and "text" in chunk:
                text_chunk = clean(chunk["text"])
                full_response += text_chunk
                response_container.markdown(full_response)
    st.session_state.chat_history.append({"role": "assistant", "content": full_response})
    trim_memory()

if st.sidebar.button("Summarize Conversation"):
    if st.session_state.chat_history:
        history_text = "\n".join(
            [f"{msg['role'].capitalize()}: {msg['content']}" for msg in st.session_state.chat_history]
        )

        summarize_prompt = PromptTemplate(
            input_variables=["history"],
            template="Summarize the following conversation briefly:\n\n{history}\n\nSummary:"
        )

        summarize_chain = LLMChain(llm=llm, prompt=summarize_prompt)

        with st.spinner("Summarizing..."):
            summary = summarize_chain.run({"history": history_text})

        st.subheader("Summary")
        st.write(clean(summary))
    else:
        st.sidebar.warning("No conversation history to summarize.")