Spaces:
Sleeping
Sleeping
Upload 20 files
Browse filesProva Commit Frontend
- .gitattributes +2 -0
- app.py +16 -0
- frontend_pages/BasePage.py +22 -0
- frontend_pages/ChatModelPage.py +148 -0
- frontend_pages/ConfigPage.py +6 -0
- frontend_pages/Dashboard.py +72 -0
- frontend_pages/__init__.py +9 -0
- frontend_pages/__pycache__/BasePage.cpython-312.pyc +0 -0
- frontend_pages/__pycache__/ChatModelPage.cpython-312.pyc +0 -0
- frontend_pages/__pycache__/ConfigPage.cpython-312.pyc +0 -0
- frontend_pages/__pycache__/Dashboard.cpython-312.pyc +0 -0
- frontend_pages/__pycache__/__init__.cpython-312.pyc +0 -0
- frontend_pages/__pycache__/load_css.cpython-312.pyc +0 -0
- frontend_pages/__pycache__/modals.cpython-312.pyc +0 -0
- frontend_pages/load_css.py +10 -0
- frontend_pages/modals.py +113 -0
- requirements.txt +140 -0
- static/2.png +3 -0
- static/3.png +3 -0
- static/NewCallButton.png +0 -0
- static/UploadCallButton.png +0 -0
.gitattributes
CHANGED
|
@@ -33,3 +33,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
static/2.png filter=lfs diff=lfs merge=lfs -text
|
| 37 |
+
static/3.png filter=lfs diff=lfs merge=lfs -text
|
app.py
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from frontend_pages import st
|
| 2 |
+
from frontend_pages.ConfigPage import ConfigPage
|
| 3 |
+
from frontend_pages.ChatModelPage import ChatModelPage
|
| 4 |
+
from frontend_pages.Dashboard import Dashboard
|
| 5 |
+
|
| 6 |
+
st.set_page_config(layout="wide")
|
| 7 |
+
|
| 8 |
+
PAGES = {
|
| 9 |
+
"Configurazione": ConfigPage,
|
| 10 |
+
"Dashboard": ChatModelPage,
|
| 11 |
+
# "Dashboard": Dashboard,
|
| 12 |
+
}
|
| 13 |
+
|
| 14 |
+
if __name__ == "__main__":
|
| 15 |
+
PAGES[st.sidebar.selectbox("Select a page", list(PAGES.keys()))]().render()
|
| 16 |
+
# PAGES["Chat with AI Model"]().render()
|
frontend_pages/BasePage.py
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from . import st, ABC, abstractmethod
|
| 2 |
+
|
| 3 |
+
class BasePage(ABC):
|
| 4 |
+
_instance = None
|
| 5 |
+
|
| 6 |
+
def __new__(cls, *args, **kwargs):
|
| 7 |
+
if cls._instance is None:
|
| 8 |
+
cls._instance = super(BasePage, cls).__new__(cls)
|
| 9 |
+
return cls._instance
|
| 10 |
+
|
| 11 |
+
def __init__(self):
|
| 12 |
+
if not hasattr(self, 'initialized'):
|
| 13 |
+
self.api_keys = []
|
| 14 |
+
self.initialized = True
|
| 15 |
+
|
| 16 |
+
@abstractmethod
|
| 17 |
+
def render(self, keys : dict[str, str | None], **kwargs):
|
| 18 |
+
with st.sidebar:
|
| 19 |
+
st.title("API Key Input")
|
| 20 |
+
for key, default_value in keys.items():
|
| 21 |
+
st.session_state[key] = st.text_input(f"Enter API key for {key}", value=default_value, type="password")
|
| 22 |
+
st.divider()
|
frontend_pages/ChatModelPage.py
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from . import os, st, re, requests, stylable_container
|
| 2 |
+
from .BasePage import BasePage
|
| 3 |
+
|
| 4 |
+
from .modals import get_base64_image, create_call_modal, upload_call_modal_and_actions
|
| 5 |
+
|
| 6 |
+
class RouterAgent:
|
| 7 |
+
def __call__(self, **kwargs):
|
| 8 |
+
agent_prompt_slash_code = re.findall(r"(\/[\w\-_]*)? *(.*)", kwargs.get('prompt'))
|
| 9 |
+
uri = agent_prompt_slash_code[0][0] or "/explain"
|
| 10 |
+
prompt = agent_prompt_slash_code[0][1]
|
| 11 |
+
print(f'{uri = }', f'{prompt = }')
|
| 12 |
+
response = requests.post(os.getenv("BACKEND_URL", "http://127.0.0.1:5000") + f'{uri}', json = {"prompt" : prompt})
|
| 13 |
+
if response.status_code != 200:
|
| 14 |
+
st.error(f"Error: {response.text}")
|
| 15 |
+
return
|
| 16 |
+
response_json = response.json()
|
| 17 |
+
print(f'{response_json = }')
|
| 18 |
+
return response_json["message"]
|
| 19 |
+
|
| 20 |
+
class ChatModelPage(BasePage):
|
| 21 |
+
def __init__(self):
|
| 22 |
+
super().__init__()
|
| 23 |
+
self.model = None
|
| 24 |
+
self.router_agent = RouterAgent()
|
| 25 |
+
|
| 26 |
+
def render(self):
|
| 27 |
+
st.title("Dashboard")
|
| 28 |
+
self.sidebar_elements()
|
| 29 |
+
self.upfront_page()
|
| 30 |
+
self.init_messages()
|
| 31 |
+
self.reset_messages_sidebar_button()
|
| 32 |
+
# Display chat messages from history on app rerun
|
| 33 |
+
for message in st.session_state.messages:
|
| 34 |
+
with st.chat_message(message["role"]):
|
| 35 |
+
st.markdown(message["content"])
|
| 36 |
+
# React to user input
|
| 37 |
+
if prompt := st.chat_input("What is up?"):
|
| 38 |
+
# Display user message in chat message container
|
| 39 |
+
st.chat_message("user").markdown(prompt)
|
| 40 |
+
# Add user message to chat history
|
| 41 |
+
st.session_state.messages.append({"role": "user", "content": prompt})
|
| 42 |
+
response = self.get_agent_response(prompt = prompt)
|
| 43 |
+
# Display assistant response in chat message container
|
| 44 |
+
with st.chat_message("assistant"):st.markdown(response)
|
| 45 |
+
# Add assistant response to chat history
|
| 46 |
+
st.session_state.messages.append({"role": "assistant", "content": response})
|
| 47 |
+
|
| 48 |
+
def init_messages(self):
|
| 49 |
+
# Initialize chat history
|
| 50 |
+
if "messages" not in st.session_state:
|
| 51 |
+
st.session_state.messages = []
|
| 52 |
+
|
| 53 |
+
def get_agent_response(self, **kwargs):
|
| 54 |
+
# Get agent response
|
| 55 |
+
return self.router_agent(**kwargs)
|
| 56 |
+
|
| 57 |
+
def reset_messages_sidebar_button(self):
|
| 58 |
+
with st.sidebar:
|
| 59 |
+
# Reset chat history
|
| 60 |
+
if st.button("Reset chat"):
|
| 61 |
+
st.session_state.messages = []
|
| 62 |
+
|
| 63 |
+
def upfront_page(self):
|
| 64 |
+
tabs_and_dialogs_cols = st.columns(2)
|
| 65 |
+
with tabs_and_dialogs_cols[0]:
|
| 66 |
+
with stylable_container(
|
| 67 |
+
key = "create-call-button",
|
| 68 |
+
css_styles = f"""
|
| 69 |
+
button {{
|
| 70 |
+
background-image: url("data:image/png;base64,{get_base64_image("static/NewCallButton.png")}");
|
| 71 |
+
background-size: cover;
|
| 72 |
+
background-repeat: no-repeat;
|
| 73 |
+
background-position: center;
|
| 74 |
+
background-color: transparent;
|
| 75 |
+
border: none;
|
| 76 |
+
width: 298px;
|
| 77 |
+
height: 164px;
|
| 78 |
+
}}"""
|
| 79 |
+
):
|
| 80 |
+
clicked_create_call_button = st.button("", key = "create-call-button")
|
| 81 |
+
if clicked_create_call_button:create_call_modal()
|
| 82 |
+
with stylable_container(
|
| 83 |
+
key = "upload-call-button",
|
| 84 |
+
css_styles = f"""
|
| 85 |
+
button {{
|
| 86 |
+
background-image: url("data:image/png;base64,{get_base64_image("static/UploadCallButton.png")}");
|
| 87 |
+
background-size: cover;
|
| 88 |
+
background-repeat: no-repeat;
|
| 89 |
+
background-position: center;
|
| 90 |
+
background-color: transparent;
|
| 91 |
+
border: none;
|
| 92 |
+
width: 298px;
|
| 93 |
+
height: 164px;
|
| 94 |
+
}}"""
|
| 95 |
+
):
|
| 96 |
+
clicked_create_call_button = st.button('', key='upload-call-button')
|
| 97 |
+
if clicked_create_call_button:upload_call_modal_and_actions()
|
| 98 |
+
with tabs_and_dialogs_cols[1]:
|
| 99 |
+
tabs = st.tabs(["Tasks"])
|
| 100 |
+
func_of_tabs = [ self.tasks ]
|
| 101 |
+
for tab, func in zip(tabs, func_of_tabs):
|
| 102 |
+
with tab:func()
|
| 103 |
+
|
| 104 |
+
def sidebar_elements(self):
|
| 105 |
+
actions = {"Project" : self.projects, "Team" : self.team }
|
| 106 |
+
with st.sidebar:
|
| 107 |
+
for label, action in actions.items():
|
| 108 |
+
st.header(label)
|
| 109 |
+
action()
|
| 110 |
+
st.divider()
|
| 111 |
+
|
| 112 |
+
def team(self):
|
| 113 |
+
teams_per_project = {"Projects": "Team1", "Projects2": "Team2", "Projects3": "Team3"}
|
| 114 |
+
st.write(teams_per_project[st.session_state.selected_project])
|
| 115 |
+
# st.image("static/2.png")
|
| 116 |
+
|
| 117 |
+
def tasks(self):
|
| 118 |
+
st.image("static/3.png")
|
| 119 |
+
|
| 120 |
+
def projects(self):
|
| 121 |
+
projects_available = ["Projects", "Projects2", "Projects3"]
|
| 122 |
+
st.session_state.selected_project = st.selectbox("Projects available", projects_available)
|
| 123 |
+
|
| 124 |
+
# def choose_agent(self):
|
| 125 |
+
# # Choose agent
|
| 126 |
+
# class RouterAgent:
|
| 127 |
+
# def __call__(self, **kwargs):
|
| 128 |
+
# agent_prompt_slash_code = re.findall(r"(\/[\w\-_]*) *(.*)", kwargs.get('prompt'))
|
| 129 |
+
# uri = agent_prompt_slash_code[0][0]
|
| 130 |
+
# prompt = agent_prompt_slash_code[0][1]
|
| 131 |
+
# response = requests.post(os.getenv("BACKEND_URL") + f'/{uri}', json = {"prompt" : prompt})
|
| 132 |
+
# if response.status_code != 200:
|
| 133 |
+
# st.error(f"Error: {response.text}")
|
| 134 |
+
# return
|
| 135 |
+
# return response.json()
|
| 136 |
+
# # agents = {
|
| 137 |
+
# # "Dummy Agent": {
|
| 138 |
+
# # "_class" : RouterAgent,
|
| 139 |
+
# # },
|
| 140 |
+
# # "Meeting Scheduler Agent": {
|
| 141 |
+
# # "_class" : DummyAgent,
|
| 142 |
+
# # }
|
| 143 |
+
# # }
|
| 144 |
+
# # agent_selected = st.sidebar.selectbox("Select agent", list(agents.keys()))
|
| 145 |
+
# # agent_init_js = agents[agent_selected]
|
| 146 |
+
# RouterAgent()
|
| 147 |
+
# agent_class = agent_init_js.pop("_class")
|
| 148 |
+
# return agent_class(**agent_init_js)
|
frontend_pages/ConfigPage.py
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from . import os
|
| 2 |
+
from .BasePage import BasePage
|
| 3 |
+
|
| 4 |
+
class ConfigPage(BasePage):
|
| 5 |
+
def render(self):
|
| 6 |
+
super().render(keys={"WATSON_API_KEY": os.getenv("WATSON_API_KEY")})
|
frontend_pages/Dashboard.py
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from . import os, st, stylable_container
|
| 2 |
+
from .BasePage import BasePage
|
| 3 |
+
|
| 4 |
+
from .modals import get_base64_image, create_call_modal, upload_call_modal_and_actions
|
| 5 |
+
|
| 6 |
+
class Dashboard(BasePage):
|
| 7 |
+
def render(self):
|
| 8 |
+
st.title("Dashboard")
|
| 9 |
+
self.sidebar_elements()
|
| 10 |
+
self.upfront_page()
|
| 11 |
+
|
| 12 |
+
def upfront_page(self):
|
| 13 |
+
with st.sidebar:
|
| 14 |
+
tabs_and_dialogs_cols = st.columns(2)
|
| 15 |
+
with tabs_and_dialogs_cols[0]:
|
| 16 |
+
with stylable_container(
|
| 17 |
+
key = "create-call-button",
|
| 18 |
+
# css_styles = f"""
|
| 19 |
+
# button {{
|
| 20 |
+
# background-image: url("data:image/png;base64,{get_base64_image("static/NewCallButton.png")}");
|
| 21 |
+
# background-size: cover;
|
| 22 |
+
# background-repeat: no-repeat;
|
| 23 |
+
# background-position: center;
|
| 24 |
+
# background-color: transparent;
|
| 25 |
+
# border: none;
|
| 26 |
+
# width: 298px;
|
| 27 |
+
# height: 164px;
|
| 28 |
+
# }}"""
|
| 29 |
+
):
|
| 30 |
+
clicked_create_call_button = st.button("create-call-button", key = "create-call-button")
|
| 31 |
+
if clicked_create_call_button:create_call_modal()
|
| 32 |
+
with stylable_container(
|
| 33 |
+
key = "upload-call-button",
|
| 34 |
+
# css_styles = f"""
|
| 35 |
+
# button {{
|
| 36 |
+
# background-image: url("data:image/png;base64,{get_base64_image("static/UploadCallButton.png")}");
|
| 37 |
+
# background-size: cover;
|
| 38 |
+
# background-repeat: no-repeat;
|
| 39 |
+
# background-position: center;
|
| 40 |
+
# background-color: transparent;
|
| 41 |
+
# border: none;
|
| 42 |
+
# width: 298px;
|
| 43 |
+
# height: 164px;
|
| 44 |
+
# }}"""
|
| 45 |
+
):
|
| 46 |
+
clicked_create_call_button = st.button('upload-call-button', key='upload-call-button')
|
| 47 |
+
if clicked_create_call_button:upload_call_modal_and_actions()
|
| 48 |
+
with tabs_and_dialogs_cols[1]:
|
| 49 |
+
tabs = st.tabs(["Tasks"])
|
| 50 |
+
func_of_tabs = [ self.tasks ]
|
| 51 |
+
for tab, func in zip(tabs, func_of_tabs):
|
| 52 |
+
with tab:func()
|
| 53 |
+
|
| 54 |
+
def sidebar_elements(self):
|
| 55 |
+
actions = {"Project" : self.projects, "Team" : self.team }
|
| 56 |
+
with st.sidebar:
|
| 57 |
+
for label, action in actions.items():
|
| 58 |
+
st.header(label)
|
| 59 |
+
action()
|
| 60 |
+
st.divider()
|
| 61 |
+
|
| 62 |
+
def team(self):
|
| 63 |
+
teams_per_project = {"Projects": "Team1", "Projects2": "Team2", "Projects3": "Team3"}
|
| 64 |
+
st.write(teams_per_project[st.session_state.selected_project])
|
| 65 |
+
# st.image("static/2.png")
|
| 66 |
+
|
| 67 |
+
def tasks(self):
|
| 68 |
+
st.image("static/3.png")
|
| 69 |
+
|
| 70 |
+
def projects(self):
|
| 71 |
+
projects_available = ["Projects", "Projects2", "Projects3"]
|
| 72 |
+
st.session_state.selected_project = st.selectbox("Projects available", projects_available)
|
frontend_pages/__init__.py
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import streamlit as st
|
| 2 |
+
import requests
|
| 3 |
+
import re
|
| 4 |
+
import os
|
| 5 |
+
import base64
|
| 6 |
+
from abc import ABC, abstractmethod
|
| 7 |
+
from functools import partial
|
| 8 |
+
from streamlit_calendar import calendar
|
| 9 |
+
from streamlit_extras.stylable_container import stylable_container
|
frontend_pages/__pycache__/BasePage.cpython-312.pyc
ADDED
|
Binary file (1.77 kB). View file
|
|
|
frontend_pages/__pycache__/ChatModelPage.cpython-312.pyc
ADDED
|
Binary file (7.97 kB). View file
|
|
|
frontend_pages/__pycache__/ConfigPage.cpython-312.pyc
ADDED
|
Binary file (734 Bytes). View file
|
|
|
frontend_pages/__pycache__/Dashboard.cpython-312.pyc
ADDED
|
Binary file (3.73 kB). View file
|
|
|
frontend_pages/__pycache__/__init__.cpython-312.pyc
ADDED
|
Binary file (502 Bytes). View file
|
|
|
frontend_pages/__pycache__/load_css.cpython-312.pyc
ADDED
|
Binary file (725 Bytes). View file
|
|
|
frontend_pages/__pycache__/modals.cpython-312.pyc
ADDED
|
Binary file (7.8 kB). View file
|
|
|
frontend_pages/load_css.py
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from . import st
|
| 2 |
+
|
| 3 |
+
def render_css(file_path):
|
| 4 |
+
with open(file_path, 'r') as file:
|
| 5 |
+
css_content = file.read()
|
| 6 |
+
st.markdown(f'<style>{css_content}</style>', unsafe_allow_html=True)
|
| 7 |
+
|
| 8 |
+
# Example usage
|
| 9 |
+
if __name__ == "__main__":
|
| 10 |
+
render_css('path_to_your_css_file.css')
|
frontend_pages/modals.py
ADDED
|
@@ -0,0 +1,113 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import random
|
| 2 |
+
import docx
|
| 3 |
+
from PyPDF2 import PdfFileReader
|
| 4 |
+
import io
|
| 5 |
+
|
| 6 |
+
from . import st, base64, os, requests, partial
|
| 7 |
+
from .load_css import render_css
|
| 8 |
+
|
| 9 |
+
st.markdown(f'<style></style>', unsafe_allow_html=True)
|
| 10 |
+
|
| 11 |
+
def get_base64_image(image_path : str):
|
| 12 |
+
with open(image_path, "rb") as image_file:
|
| 13 |
+
return base64.b64encode(image_file.read()).decode()
|
| 14 |
+
|
| 15 |
+
@st.dialog("Create a Call")
|
| 16 |
+
def create_call_modal():
|
| 17 |
+
st.multiselect("People", ["Alice", "Bob", "Charlie"])
|
| 18 |
+
st.multiselect("Tasks", ["Task 1", "Task 2", "Task 3"])
|
| 19 |
+
st.text_area("Prompt")
|
| 20 |
+
buttons = [
|
| 21 |
+
("submit", lambda _ : st.balloons()),
|
| 22 |
+
("cancel", lambda _ : st.balloons())
|
| 23 |
+
]
|
| 24 |
+
cols = st.columns(len(buttons))
|
| 25 |
+
for col, button in zip(cols, buttons):
|
| 26 |
+
with col:
|
| 27 |
+
if st.button(button[0]):
|
| 28 |
+
button[1]()
|
| 29 |
+
|
| 30 |
+
@st.dialog("Upload a Call")
|
| 31 |
+
def upload_call_modal_and_actions():
|
| 32 |
+
uploaded_file = st.file_uploader(
|
| 33 |
+
# "Import a videocall recording or its transcripts",
|
| 34 |
+
"Import a videocall recording transcript",
|
| 35 |
+
type=['.txt', '.doc', '.docx', '.pdf'],
|
| 36 |
+
# type=['.txt', '.doc', '.docx', '.pdf', '.mp4', '.wav', '.flac'],
|
| 37 |
+
accept_multiple_files=False
|
| 38 |
+
)
|
| 39 |
+
transcript_text = get_transcript_text(uploaded_file) if uploaded_file else ""
|
| 40 |
+
buttons = {
|
| 41 |
+
# "Crea minuta": minuta_action_from_uploaded_call,
|
| 42 |
+
# "Genera trascritto": transcript_action_from_uploaded_call,
|
| 43 |
+
"QA from transcripts": partial(qa_from_transcripts, Transcript = transcript_text),
|
| 44 |
+
"Generate Tasks from transcript": partial(create_tasks_action_from_uploaded_call_transcript, Transcript = transcript_text),
|
| 45 |
+
}
|
| 46 |
+
_ = buttons[st.selectbox("Choose an action", buttons.keys())]()
|
| 47 |
+
|
| 48 |
+
def minuta_action_from_uploaded_call():
|
| 49 |
+
if st.button("Crea minuta"):
|
| 50 |
+
st.download_button("Scarica minuta", data = "moc_minuta.txt")
|
| 51 |
+
|
| 52 |
+
def transcript_action_from_uploaded_call():
|
| 53 |
+
if st.button("Crea transcript"):
|
| 54 |
+
st.download_button("Scarica transcript", data = "moc_transcript.txt")
|
| 55 |
+
|
| 56 |
+
def get_transcript_text(uploaded_file):
|
| 57 |
+
if uploaded_file is not None:
|
| 58 |
+
file_extension = os.path.splitext(uploaded_file.name)[1].lower()
|
| 59 |
+
if file_extension == '.txt':
|
| 60 |
+
return get_text_from_txt(uploaded_file)
|
| 61 |
+
elif file_extension in ['.doc', '.docx']:
|
| 62 |
+
return get_text_from_doc(uploaded_file)
|
| 63 |
+
elif file_extension == '.pdf':
|
| 64 |
+
return get_text_from_pdf(uploaded_file)
|
| 65 |
+
return ""
|
| 66 |
+
|
| 67 |
+
def get_text_from_txt(uploaded_file):
|
| 68 |
+
return uploaded_file.read().decode("utf-8")
|
| 69 |
+
|
| 70 |
+
def get_text_from_doc(uploaded_file):
|
| 71 |
+
doc = docx.Document(uploaded_file)
|
| 72 |
+
return "\n".join([para.text for para in doc.paragraphs])
|
| 73 |
+
|
| 74 |
+
def get_text_from_pdf(uploaded_file):
|
| 75 |
+
reader = PdfFileReader(io.BytesIO(uploaded_file.read()))
|
| 76 |
+
text = ""
|
| 77 |
+
for page_num in range(reader.getNumPages()):
|
| 78 |
+
text += reader.getPage(page_num).extract_text()
|
| 79 |
+
return text
|
| 80 |
+
|
| 81 |
+
|
| 82 |
+
def qa_from_transcripts(Transcript : str):
|
| 83 |
+
Prompt = st.text_area("Prompt")
|
| 84 |
+
Transcript = st.text_area("Transcript")
|
| 85 |
+
Tasks = "\n\n".join(st.multiselect("Tasks", options = ["Task 1", "Task 2", "Task 3"]))
|
| 86 |
+
if st.button("QA from transcripts"):
|
| 87 |
+
response = requests.post(os.getenv("QA_TRANSCRIPT_ENDPOINT", "http://127.0.0.1:5000/transcript") ,
|
| 88 |
+
json = {
|
| 89 |
+
"prompt": Prompt,
|
| 90 |
+
"transcript" : Transcript or "",
|
| 91 |
+
"tasks": Tasks or [],
|
| 92 |
+
})
|
| 93 |
+
st.success(response.json())
|
| 94 |
+
return
|
| 95 |
+
|
| 96 |
+
def create_tasks_action_from_uploaded_call_transcript(Transcript : str):
|
| 97 |
+
|
| 98 |
+
if st.button("create_tasks"):
|
| 99 |
+
response = requests.post(os.getenv("QA_TRANSCRIPT_ENDPOINT", "http://127.0.0.1:5000/tasks/from_transcript") , json = {"transcript" : Transcript})
|
| 100 |
+
st.session_state.tasks = st.success(response.json())
|
| 101 |
+
return
|
| 102 |
+
if st.session_state.get('tasks'):
|
| 103 |
+
task = st.selectbox("Select a task", st.session_state.tasks)
|
| 104 |
+
task_matchmaking(task)
|
| 105 |
+
|
| 106 |
+
def task_matchmaking(task : str):
|
| 107 |
+
cols = st.columns(2)
|
| 108 |
+
with cols[0]:
|
| 109 |
+
st.markdown("### Task matchmaking")
|
| 110 |
+
with cols[1]:
|
| 111 |
+
st.multiselect("People", ["Alice", "Bob", "Charlie"])
|
| 112 |
+
if st.button("Assign"):
|
| 113 |
+
st.success("Task assigned")
|
requirements.txt
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
altair==5.5.0
|
| 2 |
+
annotated-types==0.7.0
|
| 3 |
+
anyio==4.8.0
|
| 4 |
+
attrs==25.1.0
|
| 5 |
+
beautifulsoup4==4.13.3
|
| 6 |
+
blinker==1.9.0
|
| 7 |
+
cachetools==5.5.2
|
| 8 |
+
certifi==2025.1.31
|
| 9 |
+
charset-normalizer==3.4.1
|
| 10 |
+
click==8.1.8
|
| 11 |
+
colorama==0.4.6
|
| 12 |
+
contourpy==1.3.1
|
| 13 |
+
cycler==0.12.1
|
| 14 |
+
entrypoints==0.4
|
| 15 |
+
Faker==36.1.1
|
| 16 |
+
fastapi==0.115.8
|
| 17 |
+
favicon==0.7.0
|
| 18 |
+
fonttools==4.56.0
|
| 19 |
+
gitdb==4.0.12
|
| 20 |
+
GitPython==3.1.44
|
| 21 |
+
google-api-core==2.24.1
|
| 22 |
+
google-api-python-client==2.161.0
|
| 23 |
+
google-auth==2.38.0
|
| 24 |
+
google-auth-httplib2==0.2.0
|
| 25 |
+
google-auth-oauthlib==1.2.1
|
| 26 |
+
google-cloud==0.34.0
|
| 27 |
+
google-cloud-core==2.4.2
|
| 28 |
+
google-cloud-storage==3.0.0
|
| 29 |
+
google-cloud-vision==3.10.0
|
| 30 |
+
google-crc32c==1.6.0
|
| 31 |
+
google-resumable-media==2.7.2
|
| 32 |
+
googleapis-common-protos==1.68.0
|
| 33 |
+
gritql==0.1.5
|
| 34 |
+
grpcio==1.70.0
|
| 35 |
+
grpcio-status==1.70.0
|
| 36 |
+
h11==0.14.0
|
| 37 |
+
htbuilder==0.9.0
|
| 38 |
+
httpcore==1.0.7
|
| 39 |
+
httplib2==0.22.0
|
| 40 |
+
httpx==0.28.1
|
| 41 |
+
ibm-cos-sdk==2.13.6
|
| 42 |
+
ibm-cos-sdk-core==2.13.6
|
| 43 |
+
ibm-cos-sdk-s3transfer==2.13.6
|
| 44 |
+
ibm_watsonx_ai==1.2.8
|
| 45 |
+
idna==3.10
|
| 46 |
+
importlib_metadata==8.6.1
|
| 47 |
+
Jinja2==3.1.5
|
| 48 |
+
jmespath==1.0.1
|
| 49 |
+
jsonpatch==1.33
|
| 50 |
+
jsonpointer==3.0.0
|
| 51 |
+
jsonschema==4.23.0
|
| 52 |
+
jsonschema-specifications==2024.10.1
|
| 53 |
+
kiwisolver==1.4.8
|
| 54 |
+
langchain-cli==0.0.35
|
| 55 |
+
langchain-core==0.3.37
|
| 56 |
+
langchain-ibm==0.3.6
|
| 57 |
+
langgraph==0.2.74
|
| 58 |
+
langgraph-checkpoint==2.0.16
|
| 59 |
+
langgraph-sdk==0.1.53
|
| 60 |
+
langserve==0.3.1
|
| 61 |
+
langsmith==0.3.9
|
| 62 |
+
lomond==0.3.3
|
| 63 |
+
lxml==5.3.1
|
| 64 |
+
Markdown==3.7
|
| 65 |
+
markdown-it-py==3.0.0
|
| 66 |
+
markdownlit==0.0.7
|
| 67 |
+
MarkupSafe==3.0.2
|
| 68 |
+
matplotlib==3.10.0
|
| 69 |
+
mdurl==0.1.2
|
| 70 |
+
msgpack==1.1.0
|
| 71 |
+
narwhals==1.27.1
|
| 72 |
+
numpy==1.26.4
|
| 73 |
+
oauthlib==3.2.2
|
| 74 |
+
orjson==3.10.15
|
| 75 |
+
packaging==24.2
|
| 76 |
+
pandas==2.1.4
|
| 77 |
+
pillow==11.1.0
|
| 78 |
+
plotly==6.0.0
|
| 79 |
+
prometheus_client==0.21.1
|
| 80 |
+
proto-plus==1.26.0
|
| 81 |
+
protobuf==5.29.3
|
| 82 |
+
pyarrow==19.0.1
|
| 83 |
+
pyasn1==0.6.1
|
| 84 |
+
pyasn1_modules==0.4.1
|
| 85 |
+
pydantic==2.10.6
|
| 86 |
+
pydantic_core==2.27.2
|
| 87 |
+
pydeck==0.9.1
|
| 88 |
+
Pygments==2.19.1
|
| 89 |
+
pymdown-extensions==10.14.3
|
| 90 |
+
pyparsing==3.2.1
|
| 91 |
+
PyPDF2==3.0.1
|
| 92 |
+
python-dateutil==2.9.0.post0
|
| 93 |
+
python-docx==1.1.2
|
| 94 |
+
python-dotenv==1.0.1
|
| 95 |
+
pytz==2025.1
|
| 96 |
+
PyYAML==6.0.2
|
| 97 |
+
referencing==0.36.2
|
| 98 |
+
requests==2.32.2
|
| 99 |
+
requests-oauthlib==2.0.0
|
| 100 |
+
requests-toolbelt==1.0.0
|
| 101 |
+
rich==13.9.4
|
| 102 |
+
rpds-py==0.23.1
|
| 103 |
+
rsa==4.9
|
| 104 |
+
setuptools==75.8.0
|
| 105 |
+
shellingham==1.5.4
|
| 106 |
+
six==1.17.0
|
| 107 |
+
smmap==5.0.2
|
| 108 |
+
sniffio==1.3.1
|
| 109 |
+
soupsieve==2.6
|
| 110 |
+
SQLAlchemy==2.0.38
|
| 111 |
+
sse-starlette==1.8.2
|
| 112 |
+
st-annotated-text==4.0.2
|
| 113 |
+
st-theme==1.2.3
|
| 114 |
+
starlette==0.45.3
|
| 115 |
+
streamlit==1.42.2
|
| 116 |
+
streamlit-calendar==1.2.1
|
| 117 |
+
streamlit-camera-input-live==0.2.0
|
| 118 |
+
streamlit-card==1.0.2
|
| 119 |
+
streamlit-embedcode==0.1.2
|
| 120 |
+
streamlit-extras==0.5.5
|
| 121 |
+
streamlit-faker==0.0.3
|
| 122 |
+
streamlit-image-coordinates==0.1.9
|
| 123 |
+
streamlit-keyup==0.3.0
|
| 124 |
+
streamlit-toggle-switch==1.0.2
|
| 125 |
+
streamlit-vertical-slider==2.5.5
|
| 126 |
+
tabulate==0.9.0
|
| 127 |
+
tenacity==9.0.0
|
| 128 |
+
toml==0.10.2
|
| 129 |
+
tomlkit==0.13.2
|
| 130 |
+
tornado==6.4.2
|
| 131 |
+
typer==0.9.4
|
| 132 |
+
typing_extensions==4.12.2
|
| 133 |
+
tzdata==2025.1
|
| 134 |
+
uritemplate==4.1.1
|
| 135 |
+
urllib3==2.3.0
|
| 136 |
+
uvicorn==0.34.0
|
| 137 |
+
validators==0.34.0
|
| 138 |
+
wheel==0.45.1
|
| 139 |
+
zipp==3.21.0
|
| 140 |
+
zstandard==0.23.0
|
static/2.png
ADDED
|
Git LFS Details
|
static/3.png
ADDED
|
Git LFS Details
|
static/NewCallButton.png
ADDED
|
static/UploadCallButton.png
ADDED
|