From b9310364df77dedb32b581c80da026a468c3030b Mon Sep 17 00:00:00 2001 From: "Samuele E. Locatelli" Date: Thu, 21 Aug 2025 16:03:38 +0000 Subject: [PATCH] Add REDIS session --- streamlit/app.py | 98 ++++++++++++++++++++++++++++++------------- streamlit/app.py.orig | 66 +++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+), 29 deletions(-) create mode 100644 streamlit/app.py.orig diff --git a/streamlit/app.py b/streamlit/app.py index 627e2c8..92b584a 100644 --- a/streamlit/app.py +++ b/streamlit/app.py @@ -1,21 +1,55 @@ #### -#### Streamlit Streaming using LM Studio as OpenAI Standin -#### run with `streamlit run app.py` - -# !pip install pypdf langchain langchain_openai +#### Streamlit Streaming using LM Studio + Redis for multi-user context +#### run with: streamlit run app.py +#### Requires: pip install pypdf langchain langchain_openai redis import streamlit as st +import redis +import json +import uuid from langchain_core.messages import AIMessage, HumanMessage from langchain_openai import ChatOpenAI from langchain_core.output_parsers import StrOutputParser from langchain_core.prompts import ChatPromptTemplate -# app config -st.set_page_config(page_title="Egalware Chatbot", page_icon="🤖") -st.title("Egalware's Streaming Chatbot") +# --------------------- +# Redis connection +# --------------------- +# Adjust host/port as needed +r = redis.Redis(host="localhost", port=6379, db=1, decode_responses=True) +# --------------------- +# Helpers for session & history +# --------------------- +def get_session_id(): + """Ensure each user gets a unique, persistent session ID.""" + if "session_id" not in st.session_state: + st.session_state.session_id = str(uuid.uuid4()) + return st.session_state.session_id + +def load_history(session_id): + """Retrieve chat history for a given session from Redis.""" + raw = r.get(f"chatbot:history:{session_id}") + if raw: + messages = json.loads(raw) + return [AIMessage(content=m["content"]) if m["type"] == "ai" + else HumanMessage(content=m["content"]) + for m in messages] + return [AIMessage(content="Hello, I am EgalWare's current ChatBot. How can I help you? (puoi fare domande in italiano, ma in inglese funziona meglio...)")] + +def save_history(session_id, history): + """Save chat history back to Redis.""" + messages = [] + for m in history: + messages.append({"type": "ai" if isinstance(m, AIMessage) else "human", "content": m.content}) + r.set(f"chatbot:history:{session_id}", json.dumps(messages)) + # Optional TTL so old sessions expire: + r.expire(f"chatbot:history:{session_id}", 60 * 60 * 24 * 7) # 7 days + +# --------------------- +# LLM interaction +# --------------------- def get_response(user_query, chat_history): - template = """ You are a helpful assistant. Answer the following questions considering the history of the conversation: @@ -23,44 +57,50 @@ def get_response(user_query, chat_history): User question: {user_question} """ - prompt = ChatPromptTemplate.from_template(template) - # Using LM Studio Local Inference Server - llm = ChatOpenAI(base_url="http://10.74.83.100:1234/v1",api_key="lm-studio", model="qwen/qwen3-4b-2507") + llm = ChatOpenAI( + base_url="http://10.74.83.100:1234/v1", + api_key="lm-studio", + model="qwen/qwen3-4b-2507" + ) chain = prompt | llm | StrOutputParser() - + return chain.stream({ "chat_history": chat_history, "user_question": user_query, }) -# session state -if "chat_history" not in st.session_state: - st.session_state.chat_history = [ - AIMessage(content="Hello, I am a bot. How can I help you?"), - ] +# --------------------- +# Streamlit app setup +# --------------------- +st.set_page_config(page_title="Egalware Chatbot", page_icon="🤖") +st.title("Egalware's Chatbot") - -# conversation +# Identify user & load history from Redis +session_id = get_session_id() +st.session_state.chat_history = load_history(session_id) + +# Render conversation for message in st.session_state.chat_history: - if isinstance(message, AIMessage): - with st.chat_message("AI"): - st.write(message.content) - elif isinstance(message, HumanMessage): - with st.chat_message("Human"): - st.write(message.content) + role = "AI" if isinstance(message, AIMessage) else "Human" + with st.chat_message(role): + st.write(message.content) -# user input +# Handle new input user_query = st.chat_input("Type your message here...") -if user_query is not None and user_query != "": +if user_query: st.session_state.chat_history.append(HumanMessage(content=user_query)) with st.chat_message("Human"): st.markdown(user_query) with st.chat_message("AI"): - response = st.write_stream(get_response(user_query, st.session_state.chat_history)) + response_text = st.write_stream(get_response(user_query, st.session_state.chat_history)) + st.session_state.chat_history.append(AIMessage(content=response_text)) + + # Save updated history to Redis + save_history(session_id, st.session_state.chat_history) + - st.session_state.chat_history.append(AIMessage(content=response)) diff --git a/streamlit/app.py.orig b/streamlit/app.py.orig new file mode 100644 index 0000000..8f78b58 --- /dev/null +++ b/streamlit/app.py.orig @@ -0,0 +1,66 @@ +#### +#### Streamlit Streaming using LM Studio as OpenAI Standin +#### run with `streamlit run app.py` + +# !pip install pypdf langchain langchain_openai + +import streamlit as st +from langchain_core.messages import AIMessage, HumanMessage +from langchain_openai import ChatOpenAI +from langchain_core.output_parsers import StrOutputParser +from langchain_core.prompts import ChatPromptTemplate + +# app config +st.set_page_config(page_title="Egalware Chatbot", page_icon="🤖") +st.title("Egalware's Chatbot") + +def get_response(user_query, chat_history): + + template = """ + You are a helpful assistant. Answer the following questions considering the history of the conversation: + + Chat history: {chat_history} + + User question: {user_question} + """ + + prompt = ChatPromptTemplate.from_template(template) + + # Using LM Studio Local Inference Server + llm = ChatOpenAI(base_url="http://10.74.83.100:1234/v1",api_key="lm-studio", model="qwen/qwen3-4b-2507") + + chain = prompt | llm | StrOutputParser() + + return chain.stream({ + "chat_history": chat_history, + "user_question": user_query, + }) + +# session state +if "chat_history" not in st.session_state: + st.session_state.chat_history = [ + AIMessage(content="Hello, I am EgalWare's current ChatBot. How can I help you? (puoi fare domande in italiano, ma in inglese funziona meglio...)"), + ] + + +# conversation +for message in st.session_state.chat_history: + if isinstance(message, AIMessage): + with st.chat_message("AI"): + st.write(message.content) + elif isinstance(message, HumanMessage): + with st.chat_message("Human"): + st.write(message.content) + +# user input +user_query = st.chat_input("Type your message here...") +if user_query is not None and user_query != "": + st.session_state.chat_history.append(HumanMessage(content=user_query)) + + with st.chat_message("Human"): + st.markdown(user_query) + + with st.chat_message("AI"): + response = st.write_stream(get_response(user_query, st.session_state.chat_history)) + + st.session_state.chat_history.append(AIMessage(content=response))