Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: summarize page in UI #114

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ui/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
st.Page(page="pages/chat.py", title="Chat", icon=":material/chat:"),
st.Page(page="pages/documents.py", title="Documents", icon=":material/file_copy:"),
st.Page(page="pages/transcription.py", title="Transcription", icon=":material/graphic_eq:"),
st.Page(page="pages/summarize.py", title="Summarize", icon=":material/contract_edit:"),
]
)
pg.run()
4 changes: 2 additions & 2 deletions ui/pages/chat.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import logging
import traceback


import streamlit as st

from config import INTERNET_COLLECTION_DISPLAY_ID
from utils import generate_stream, get_collections, get_models, header
from utils.chat import generate_stream
from utils.common import get_collections, get_models, header

API_KEY = header()

Expand Down
3 changes: 2 additions & 1 deletion ui/pages/documents.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
import streamlit as st

from config import PRIVATE_COLLECTION_TYPE
from utils import create_collection, delete_collection, delete_document, header, load_data, upload_file
from utils.common import header
from utils.documents import create_collection, delete_collection, delete_document, load_data, upload_file

API_KEY = header()

Expand Down
175 changes: 175 additions & 0 deletions ui/pages/summarize.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
import time

from openai import OpenAI
import streamlit as st
from streamlit_extras.stylable_container import stylable_container

from config import BASE_URL, PRIVATE_COLLECTION_TYPE
from utils.common import get_collections, get_documents, get_models, header
from utils.summarize import generate_toc

# Config
API_KEY = header()

openai_client = OpenAI(base_url=BASE_URL, api_key=API_KEY)

# Data
try:
language_models, embeddings_models, _, _ = get_models(api_key=API_KEY)
collections = get_collections(api_key=API_KEY)
collections = [collection for collection in collections if collection["type"] == PRIVATE_COLLECTION_TYPE]
documents = get_documents(api_key=API_KEY, collection_ids=[collection["id"] for collection in collections])
except Exception as e:
st.error(body="Error to fetch user data.")
st.stop()

# State
if "selected_model" not in st.session_state:
st.session_state.selected_model = language_models[0]

# Sidebar
with st.sidebar:
new_chat = st.button(label="**:material/refresh: New summarize**", key="new", use_container_width=True)
if new_chat:
st.session_state.pop("collection_id", None)
st.session_state.pop("document_id", None)
st.session_state.pop("validate_toc", None)
st.session_state.pop("toc", None)
st.session_state.pop("summary", None)
st.rerun()
params = {"sampling_params": dict()}

st.subheader(body="Summarize parameters")
st.session_state["selected_model"] = st.selectbox(
label="Language model", options=language_models, index=language_models.index(st.session_state.selected_model)
)
params["sampling_params"]["model"] = st.session_state["selected_model"]
params["sampling_params"]["temperature"] = st.slider(label="Temperature", value=0.2, min_value=0.0, max_value=1.0, step=0.1)

# Main
## Document
st.session_state.collection_id = None if "collection_id" not in st.session_state else st.session_state.collection_id
st.session_state.document_id = None if "document_id" not in st.session_state else st.session_state.document_id

st.subheader(":material/counter_1: Select a document")
st.info("Please select a document to generate a summary.")
document = st.selectbox("Document", options=[f"{document["id"]} - {document["name"]}" for document in documents])
document_id = document.split(" - ")[0]
collection_id = [document["collection_id"] for document in documents if document["id"] == document_id][0]

with stylable_container(
key="Summarize",
css_styles="""
button{
float: right;
}
""",
):
if st.button(label="Validate", key="validate_document"):
st.session_state.collection_id = collection_id
st.session_state.document_id = document_id
st.toast("Document validated !", icon="✅")
time.sleep(2)
st.rerun()

## TOC
st.session_state.toc = "" if "toc" not in st.session_state else st.session_state.toc
st.session_state.validate_toc = False if "validate_toc" not in st.session_state else st.session_state.validate_toc

st.markdown("***")
st.markdown(f"**state:**\n{st.session_state.toc}")
st.subheader(":material/counter_2: Create a table of content")

if not st.session_state.document_id:
st.stop()

st.info(
body="For help the model to generate a summarize, you need to write a table of content of your document. Clic on *generate* button if you need an AI help."
)

toc = st.text_area(label="Table of content", value=st.session_state.toc, height=200)

with stylable_container(
key="Summarize",
css_styles="""
.left-button {
float: left;
}
.right-button {
float: right;
.stButton {
width: auto;
}
""",
):
col1, col2, col3 = st.columns([2, 6, 2])
with col1:
if st.button(label="✨ Generate", key="generate_toc", use_container_width=True):
with st.spinner("✨ Generate..."):
st.session_state.toc = generate_toc(
collection_id=collections[0]["id"], document_id=document_id, api_key=API_KEY, model=st.session_state.selected_model
)
st.toast(body="Table of content generated !", icon="✅")
time.sleep(2)
st.rerun()
with col3:
if st.button(label="Validate", use_container_width=True):
if toc:
st.session_state.toc = toc
st.session_state.validate_toc = True
st.toast(body="Table of content validated !", icon="✅")
time.sleep(2)
st.rerun()
else:
st.toast(body="You have to write a table of content before validate it.", icon="❌")


## Summary
st.session_state.summary = "" if "summary" not in st.session_state else st.session_state.summary

st.markdown(body="***")
st.markdown(body=f"**state:**\n{st.session_state.summary}")
st.subheader(body=":material/counter_3: Generate a summary")

if not st.session_state.validate_toc:
st.stop()

st.info("Here is the summary of your document.")

st.write("**Summary**")
st.code(st.session_state.summary, language="markdown", wrap_lines=True)

with stylable_container(
key="Summarize",
css_styles="""
button{
float: right;
}
""",
):
if st.button("Generate", key="generate_summary"):
with st.spinner("✨ Generate..."):
st.session_state.summary = "Generation" # @TODO
st.toast("Summary generated !", icon="✅")
time.sleep(2)
st.rerun()

feedback = st.text_area(label="Feedback")

with stylable_container(
key="Summarize",
css_styles="""
button{
float: right;
}
""",
):
if st.button("Give feedback", key="give_feedback"):
if st.session_state.summary:
with st.spinner("✨ Generate..."):
st.session_state.summary = "Generation with feedback" # @TODO
st.toast("Summary generated with feedback !", icon="✅")
time.sleep(2)
st.rerun()
else:
st.toast("You have to generate a summary before give feedback.", icon="❌")
22 changes: 11 additions & 11 deletions ui/pages/transcription.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@
import streamlit as st

from config import BASE_URL, SUPPORTED_LANGUAGES
from utils import get_models, header
from utils.common import get_models, header

API_KEY = header()

# Data
try:
_, _, audio_models, _ = get_models(api_key=API_KEY)
except Exception:
st.error("Error to fetch user data.")
st.error(body="Error to fetch user data.")
logging.error(traceback.format_exc())
st.stop()

Expand All @@ -22,28 +22,28 @@
# Sidebar
with st.sidebar:
params = {}
st.subheader("Audio parameters")
st.subheader(body="Audio parameters")
params["model"] = st.selectbox(label="Audio model", options=audio_models)
params["temperature"] = st.slider(label="Temperature", value=0.2, min_value=0.0, max_value=1.0, step=0.1)
params["language"] = st.selectbox(label="Language", options=SUPPORTED_LANGUAGES, index=SUPPORTED_LANGUAGES.index("french"))

# Main
col1, col2 = st.columns(2)
file = st.file_uploader("Upload an audio file", type=["mp3", "wav", "m4a"])
col1, col2 = st.columns(spec=2)
file = st.file_uploader(label="Upload an audio file", type=["mp3", "wav", "m4a"])
record = st.audio_input(label="Record a voice message")

if file and record:
st.error("Please upload only one file at a time.")
st.error(body="Please upload only one file at a time.")
st.stop()

audio = record or file
result = None
_, center, _ = st.columns(spec=3)
with center:
submit = st.button("**Transcribe**", use_container_width=True)
submit = st.button(label="**Transcribe**", use_container_width=True)

if submit and audio:
with st.spinner("Transcribing audio..."):
with st.spinner(text="Transcribing audio..."):
try:
response = openai_client.audio.transcriptions.create(
file=audio,
Expand All @@ -52,9 +52,9 @@
)
result = response.text
except Exception:
st.error("Error transcribing audio.")
st.error(body="Error transcribing audio.")
logging.error(traceback.format_exc())

if result:
st.caption("Result")
st.code(result, language="markdown", wrap_lines=True)
st.caption(body="Result")
st.code(body=result, language="markdown", wrap_lines=True)
Loading