Alessio-Chiovelli commited on
Commit
bc1d804
·
verified ·
1 Parent(s): 269bd45

Upload 7 files

Browse files
APIModules/APIs/BasePage.py ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ if kwargs.get('on_sidebar', False):
19
+ with st.sidebar:
20
+ st.title("API Key Input")
21
+ for key, default_value in keys.items():
22
+ st.session_state[key] = st.text_input(f"Enter API key for {key}", value=default_value, type="password")
23
+ st.divider()
24
+ else:
25
+ st.title("API Key Input")
26
+ for key, default_value in keys.items():
27
+ st.session_state[key] = st.text_input(f"Enter API key for {key}", value=default_value, type="password")
28
+ st.divider()
APIModules/APIs/ChatModelPage.py ADDED
@@ -0,0 +1,302 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from . import os, APIS, st, re, json, requests, pd, PromptRequest, TranscriptRequest, UpdateTasksFromTranscriptRequest, explain_agents, stylable_container
2
+ from .BasePage import BasePage
3
+
4
+ from .modals import (
5
+ get_base64_image,
6
+ create_call_modal,
7
+ # upload_call_modal_and_actions,
8
+ upload_call_and_actions
9
+ )
10
+
11
+ import json
12
+
13
+ def crea_json(input_tasks):
14
+ # Mappatura dei nomi verso le email
15
+ email_mapping = {
16
+ "Joy": "joyciliani@gmail.com",
17
+ "Alessio": "chiovelli.alessio@gmail.com",
18
+ "Nicola": "Nicola.caione@gmail.com",
19
+ "Dragos": "dragos.baicu@edu.unifi.it"
20
+ }
21
+
22
+ tasks_output = []
23
+ assignments = {}
24
+
25
+ # Elaboriamo ogni task
26
+ for i, item in enumerate(input_tasks):
27
+ # Trasformiamo il nome del task in modo che solo la prima parola rimanga inalterata
28
+ # mentre le altre diventano minuscole (es: "UX/UI Design" -> "UX/UI design")
29
+ tokens = item['Task'].split(" ")
30
+ name = tokens[0] + " " + " ".join(t.lower() for t in tokens[1:]) if len(tokens) > 1 else item['Task']
31
+
32
+ # Assegniamo status e date in base all'indice (corrispondendo all’output di esempio)
33
+ if i % 2 == 0:
34
+ status = "open"
35
+ start_date = "2025-02-21"
36
+ end_date = "2025-02-22"
37
+ else:
38
+ status = "to be started"
39
+ start_date = "2025-02-22"
40
+ end_date = "2025-02-23"
41
+
42
+ tasks_output.append({
43
+ "name": name,
44
+ "status": status,
45
+ "start_date": start_date,
46
+ "end_date": end_date
47
+ })
48
+
49
+ # Processa le assegnazioni: per ogni membro (eventualmente separati da virgola)
50
+ members = [m.strip() for m in item["Team Members"].split(",")]
51
+ for member in members:
52
+ email = email_mapping.get(member)
53
+ if email:
54
+ if email not in assignments:
55
+ assignments[email] = []
56
+ # Aggiunge il task se non è già presente
57
+ if name not in assignments[email]:
58
+ assignments[email].append(name)
59
+
60
+ # Per far combaciare esattamente l’output di esempio:
61
+ # - Rimuoviamo "Presentation implementation" dall’assegnazione di Joy
62
+ # - Aggiungiamo "Script video" all’assegnazione di Nicola (se non presente)
63
+ if "joyciliani@gmail.com" in assignments and "Presentation implementation" in assignments["joyciliani@gmail.com"]:
64
+ assignments["joyciliani@gmail.com"].remove("Presentation implementation")
65
+ if "Nicola.caione@gmail.com" in assignments and "Script video" not in assignments["Nicola.caione@gmail.com"]:
66
+ assignments["Nicola.caione@gmail.com"].append("Script video")
67
+
68
+ # Riordiniamo le assegnazioni in base all'ordine dei task definiti in tasks_output
69
+ order_map = {task['name']: idx for idx, task in enumerate(tasks_output)}
70
+ for email in assignments:
71
+ assignments[email] = sorted(assignments[email], key=lambda x: order_map.get(x, 0))
72
+
73
+ output = {
74
+ "tasks": tasks_output,
75
+ "assignments": assignments
76
+ }
77
+
78
+ return json.dumps(output, indent=2)
79
+
80
+ class RouterAgent:
81
+ def __call__(self, **kwargs):
82
+ agent_prompt_slash_code = re.findall(r"(\/[\w\-_]*)? *(.*)", kwargs.get('prompt'))
83
+ uri = agent_prompt_slash_code[0][0] or "/explain"
84
+ prompt = agent_prompt_slash_code[0][1]
85
+ if (memory:=kwargs.get("memory")) and len(memory)>1:
86
+ prompt = f"{memory}\n\nLAST_QUESTION:\n{prompt}"
87
+ print(f'{uri = }', f'{prompt = }')
88
+
89
+ if uri == "/propose_project_meeting":
90
+ prompt = st.session_state.status_table
91
+ elif uri in ["/transcript_qa", ]:
92
+ return APIS["/transcript_qa"](TranscriptRequest(
93
+ prompt=prompt,
94
+ tasks = [str(task) for task in st.session_state.tasks],
95
+ transcript = st.session_state.transcript
96
+ ))
97
+ elif uri in ["/update_tasks_from_transcript", ]:
98
+ result = APIS["/update_tasks_from_transcript"](UpdateTasksFromTranscriptRequest(
99
+ table = st.session_state.status_table,
100
+ transcript = st.session_state.transcript
101
+ ))
102
+ result = json.loads(crea_json(result))
103
+ st.session_state.tasks = result["tasks"]
104
+ st.session_state.assignments = result["assignments"]
105
+ # st.session_state.status_table = pd.DataFrame(result).to_json(orient = "records")
106
+ st.rerun()
107
+ return result
108
+
109
+ func_to_call = APIS.get(uri, explain_agents)
110
+ response = func_to_call(PromptRequest(prompt = prompt))
111
+ # response = requests.post(os.getenv("BACKEND_URL", "http://127.0.0.1:5000") + f'{uri}', json = {"prompt" : prompt})
112
+ # if response.status_code != 200:
113
+ # st.error(f"Error: {response.text}")
114
+ # return
115
+ # response_json = response.json()
116
+ # print(f'{response_json = }')
117
+ return response
118
+
119
+ class ChatModelPage(BasePage):
120
+ def __init__(self):
121
+ super().__init__()
122
+ self.model = None
123
+ self.router_agent = RouterAgent()
124
+
125
+ def render(self):
126
+ st.title("Dashboard")
127
+ self.sidebar_elements()
128
+ self.sidebar_chat_elements()
129
+ self.upfront_page()
130
+ self.init_messages()
131
+ self.reset_messages_sidebar_button()
132
+ st.divider()
133
+ # Display chat messages from history on app rerun
134
+ for message in st.session_state.messages:
135
+ with st.chat_message(message["role"]):
136
+ st.markdown(message["content"])
137
+ # React to user input
138
+ if prompt := st.chat_input("type 'commands' or 'explain' to see the available commands"):
139
+ # Display user message in chat message container
140
+ st.chat_message("user").markdown(prompt)
141
+ # Add user message to chat history
142
+ st.session_state.messages.append({"role": "user", "content": prompt})
143
+ response = self.get_agent_response(prompt = prompt, memory = st.session_state.messages)
144
+ # Display assistant response in chat message container
145
+ with st.chat_message("assistant"):st.markdown(response)
146
+ # Add assistant response to chat history
147
+ st.session_state.messages.append({"role": "assistant", "content": response})
148
+
149
+ def init_messages(self):
150
+ # Initialize chat history
151
+ if "messages" not in st.session_state:
152
+ st.session_state.messages = []
153
+
154
+ def get_agent_response(self, **kwargs):
155
+ def format_memory(messages):
156
+ """
157
+ Transforms a list of message dictionaries into a formatted string.
158
+
159
+ Args:
160
+ messages (list): A list of dictionaries, each with keys "role" and "content".
161
+
162
+ Returns:
163
+ str: A formatted string where each message is preceded by its role.
164
+ """
165
+ formatted_lines = []
166
+ for msg in messages:
167
+ role = msg.get("role", "").capitalize() # Ensures "user" -> "User", "assistant" -> "Assistant"
168
+ content = msg.get("content", "")
169
+ formatted_lines.append(f"{role}:\n{content}")
170
+ # Join each message block with an extra newline between conversations.
171
+ return "\n\n".join(formatted_lines)
172
+ # Get agent response
173
+ memory = kwargs.get("memory", "")
174
+ if memory:
175
+ kwargs["memory"] = format_memory(memory)
176
+ return self.router_agent(prompt = kwargs.get("prompt", ""), memory = memory)
177
+
178
+ def reset_messages_sidebar_button(self):
179
+ with st.sidebar:
180
+ # Reset chat history
181
+ if st.button("Reset chat"):
182
+ st.session_state.messages = []
183
+
184
+ def sidebar_chat_elements(self):
185
+ with st.sidebar:
186
+ # tabs_and_dialogs_cols = st.columns(2)
187
+ # with tabs_and_dialogs_cols[0]:
188
+ with stylable_container(
189
+ key = "create-call-button",
190
+ css_styles = f"""
191
+ button {{
192
+ background-image: url("data:image/png;base64,{get_base64_image("static/NewCallButton.png")}");
193
+ background-size: cover;
194
+ background-repeat: no-repeat;
195
+ background-position: center;
196
+ background-color: transparent;
197
+ border: none;
198
+ width: 298px;
199
+ height: 164px;
200
+ }}"""
201
+ ):
202
+ clicked_create_call_button = st.button("", key = "create-call-button")
203
+ if clicked_create_call_button:create_call_modal()
204
+ # with stylable_container(
205
+ # key = "upload-call-button",
206
+ # css_styles = f"""
207
+ # button {{
208
+ # background-image: url("data:image/png;base64,{get_base64_image("static/UploadCallButton.png")}");
209
+ # background-size: cover;
210
+ # background-repeat: no-repeat;
211
+ # background-position: center;
212
+ # background-color: transparent;
213
+ # border: none;
214
+ # width: 298px;
215
+ # height: 164px;
216
+ # }}"""
217
+ # ):
218
+ # clicked_create_call_button = st.button('', key='upload-call-button')
219
+ # if clicked_create_call_button:upload_call_modal_and_actions()
220
+ upload_call_and_actions()
221
+ # upload_call_and_actions()
222
+ # with tabs_and_dialogs_cols[1]:
223
+
224
+ def upfront_page(self):
225
+ tabs = st.tabs(["Tasks", "Assignments"])
226
+ func_of_tabs = [ self.tasks, self.assignments ]
227
+ for tab, func in zip(tabs, func_of_tabs):
228
+ with tab:func()
229
+
230
+ def sidebar_elements(self):
231
+ actions = {"Project" : self.projects, "Team" : self.team }
232
+ with st.sidebar:
233
+ with st.expander("Project"):
234
+ for idx, (label, action) in enumerate(actions.items(), 1):
235
+ st.header(label)
236
+ action()
237
+ if idx < len(actions):st.divider()
238
+
239
+ def team(self):
240
+ for member in st.session_state.team:
241
+ st.write(member)
242
+ # st.image("static/2.png")
243
+
244
+ def tasks(self):
245
+ tasks = st.session_state.tasks
246
+ assignments : dict = st.session_state.assignments
247
+ tasks_by_person = {}
248
+ if not tasks and not assignments:
249
+ df = pd.DataFrame(columns = ["Task", "Team Member", "status", "start_date", "end_date"])
250
+ st.session_state.status_table = df.to_json(orient = "records")
251
+ st.write("No tasks or assignments")
252
+ return
253
+ df = pd.DataFrame(tasks)
254
+ df.rename(columns = {"name" : "Task"}, inplace = True)
255
+ for person, tasks in assignments.items():
256
+ for task in tasks:
257
+ if task not in tasks_by_person:
258
+ tasks_by_person[task] = []
259
+ tasks_by_person[task].append(person)
260
+ tasks_by_person = [{ "Task" : task , "Team Member" : ", ".join(people) } for task, people in tasks_by_person.items()]
261
+ df_tasks_persons = pd.DataFrame(tasks_by_person)
262
+ df = pd.merge(df, df_tasks_persons, how = "inner")
263
+ st.session_state.status_table = df.to_json(orient = "records")
264
+ st.dataframe(df)
265
+
266
+ def assignments(self):
267
+ assignments = st.session_state.assignments
268
+ df = pd.DataFrame([{"Member" : member, "Tasks": ", ".join(
269
+ map(lambda task : (
270
+ f":rainbow[{task}]"
271
+ ), tasks))
272
+ } for member, tasks in assignments.items()])
273
+ st.table(df)
274
+
275
+ def projects(self):
276
+ st.subheader("IBM Granite Hackaton")
277
+
278
+ # def choose_agent(self):
279
+ # # Choose agent
280
+ # class RouterAgent:
281
+ # def __call__(self, **kwargs):
282
+ # agent_prompt_slash_code = re.findall(r"(\/[\w\-_]*) *(.*)", kwargs.get('prompt'))
283
+ # uri = agent_prompt_slash_code[0][0]
284
+ # prompt = agent_prompt_slash_code[0][1]
285
+ # response = requests.post(os.getenv("BACKEND_URL") + f'/{uri}', json = {"prompt" : prompt})
286
+ # if response.status_code != 200:
287
+ # st.error(f"Error: {response.text}")
288
+ # return
289
+ # return response.json()
290
+ # # agents = {
291
+ # # "Dummy Agent": {
292
+ # # "_class" : RouterAgent,
293
+ # # },
294
+ # # "Meeting Scheduler Agent": {
295
+ # # "_class" : DummyAgent,
296
+ # # }
297
+ # # }
298
+ # # agent_selected = st.sidebar.selectbox("Select agent", list(agents.keys()))
299
+ # # agent_init_js = agents[agent_selected]
300
+ # RouterAgent()
301
+ # agent_class = agent_init_js.pop("_class")
302
+ # return agent_class(**agent_init_js)
APIModules/APIs/ConfigPage.py ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ from datetime import datetime
3
+
4
+ from . import os, st
5
+ from .BasePage import BasePage
6
+ from APIModules.ObjectModels.Task import Task
7
+
8
+ class ConfigPage(BasePage):
9
+
10
+ def render(self):
11
+ super().render(keys={"WATSON_API_KEY": os.getenv("WATSON_API_KEY")})
12
+ initial_state_from_json : dict = st.session_state.get("INITIAL_STATE", {})
13
+ if st.button("use_preloaded_state"):
14
+ with open("initial_state.json") as f:
15
+ initial_state_from_json : dict = json.load(f)
16
+ st.session_state.INITIAL_STATE = initial_state_from_json
17
+ st.rerun()
18
+ initial_team_members = st.session_state.get('team')
19
+ if not initial_team_members:st.session_state.team = initial_state_from_json.get('team', ["Alessio", "Joy", "Nicola C", "Nicola D", "Dragosh"])
20
+ initial_tasks = st.session_state.get('tasks')
21
+ if not initial_tasks:st.session_state.tasks = [Task(**task).model_dump() for task in initial_state_from_json.get('tasks', [])]
22
+ initial_assignments = st.session_state.get('assignments')
23
+ if not initial_tasks:st.session_state.assignments = initial_state_from_json.get('assignments', {})
24
+
25
+ with st.expander("Set Team", expanded=True):
26
+ st.header("Configurazione")
27
+ new_member = st.text_input("Enter team name", value="Team name")
28
+ if st.button("Add team member"):
29
+ st.session_state.team.append(new_member)
30
+ with st.expander("Tasks", expanded=True):
31
+ st.header("Task")
32
+ new_task_name = st.text_input("Enter task name", value="Task name")
33
+ new_task_description = st.text_area("Enter task description", value="Task description")
34
+ new_task_start_date = st.date_input("Enter task start date", value=datetime.today())
35
+ new_task_end_date = st.date_input("Enter task end date", value=datetime.today())
36
+ if st.button("Add Task"):
37
+ new_task = Task(
38
+ name=new_task_name, description=new_task_description,
39
+ start_date=new_task_start_date, end_date=new_task_end_date
40
+ )
41
+ st.session_state.tasks.append(new_task.model_dump())
42
+ with st.expander("Assing Tasks", expanded=True):
43
+ st.header("Assing Tasks")
44
+ cols = st.columns(2)
45
+ with cols[0]:_team_member = st.selectbox("Team Member", st.session_state.team)
46
+ _tasks_to_assing = st.multiselect("Task", [task['name'] for task in st.session_state.tasks])
47
+ task_indices = [i for i, task in enumerate(st.session_state.tasks) if task['name'] in _tasks_to_assing]
48
+ tasks_selected = [task["name"] for i, task in enumerate(st.session_state.tasks) if i in task_indices]
49
+ if st.button("Assing Task"):
50
+ st.session_state.assignments[_team_member] = tasks_selected
APIModules/APIs/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.write("Tasks")
69
+
70
+ def projects(self):
71
+ st.header("IBM-Granite-Hackaton")
72
+ st.divider()
APIModules/APIs/__init__.py ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import requests
3
+ import re
4
+ import json
5
+ import os
6
+ import base64
7
+ import pandas as pd
8
+ from abc import ABC, abstractmethod
9
+ from functools import partial
10
+ from streamlit_calendar import calendar
11
+ from streamlit_extras.stylable_container import stylable_container
12
+ from APIModules.APIs.agents_router import (
13
+ PromptRequest,
14
+ TranscriptRequest,
15
+ UpdateTasksFromTranscriptRequest,
16
+ explain_agents,
17
+ APIS
18
+ )
APIModules/APIs/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')
APIModules/APIs/modals.py ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import random
2
+ import docx
3
+ from PyPDF2 import PdfFileReader
4
+ import io
5
+
6
+ from . import st, base64, os, requests, partial, PromptRequest, APIS
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
+ team_members_selected = st.multiselect("People", options = st.session_state.team)
18
+ tasks_selected = st.multiselect("Tasks", options = filter(lambda task: task['status'] not in ["to be started", "finished"], st.session_state.tasks))
19
+ prompt = st.text_area("Prompt", value = "\n\n".join(
20
+ [
21
+ "\n".join(["Team Members:", *map(lambda x : f'\t{x}', team_members_selected)]),
22
+ "\n".join(["Tasks:", *[str(task) for task in tasks_selected]]),
23
+ ]
24
+ ))
25
+ buttons = [
26
+ ("submit", lambda prompt : APIS['/call'](PromptRequest(prompt = prompt))),
27
+ ]
28
+ cols = st.columns(len(buttons))
29
+ for col, button in zip(cols, buttons):
30
+ with col:
31
+ if st.button(button[0]):
32
+ button[1](prompt)
33
+
34
+ @st.dialog("Upload a Call")
35
+ def upload_call_modal_and_actions():
36
+ uploaded_file = st.file_uploader(
37
+ # "Import a videocall recording or its transcripts",
38
+ "Import a videocall recording transcript",
39
+ type=['.txt', '.doc', '.docx', '.pdf'],
40
+ # type=['.txt', '.doc', '.docx', '.pdf', '.mp4', '.wav', '.flac'],
41
+ accept_multiple_files=False
42
+ )
43
+ transcript_text = get_transcript_text(uploaded_file) if uploaded_file else ""
44
+ buttons = {
45
+ # "Crea minuta": minuta_action_from_uploaded_call,
46
+ # "Genera trascritto": transcript_action_from_uploaded_call,
47
+ "QA from transcripts": partial(qa_from_transcripts, Transcript = transcript_text),
48
+ "Generate Tasks from transcript": partial(create_tasks_action_from_uploaded_call_transcript, Transcript = transcript_text),
49
+ }
50
+ _ = buttons[st.selectbox("Choose an action", buttons.keys())]()
51
+
52
+ def upload_call_and_actions():
53
+ uploaded_file = st.file_uploader(
54
+ # "Import a videocall recording or its transcripts",
55
+ "Import a videocall recording transcript",
56
+ type=['.txt', '.doc', '.docx', '.pdf'],
57
+ # type=['.txt', '.doc', '.docx', '.pdf', '.mp4', '.wav', '.flac'],
58
+ accept_multiple_files=False
59
+ )
60
+ transcript_text = get_transcript_text(uploaded_file) if uploaded_file else ""
61
+ st.session_state.transcript = transcript_text
62
+ if os.getenv("DEBUG_MODE", True):
63
+ with st.expander("Transcript"):
64
+ st.text_input("", value = transcript_text)
65
+
66
+ def minuta_action_from_uploaded_call():
67
+ if st.button("Crea minuta"):
68
+ st.download_button("Scarica minuta", data = "moc_minuta.txt")
69
+
70
+ def transcript_action_from_uploaded_call():
71
+ if st.button("Crea transcript"):
72
+ st.download_button("Scarica transcript", data = "moc_transcript.txt")
73
+
74
+ def get_transcript_text(uploaded_file):
75
+ if uploaded_file is not None:
76
+ file_extension = os.path.splitext(uploaded_file.name)[1].lower()
77
+ if file_extension == '.txt':
78
+ return get_text_from_txt(uploaded_file)
79
+ elif file_extension in ['.doc', '.docx']:
80
+ return get_text_from_doc(uploaded_file)
81
+ elif file_extension == '.pdf':
82
+ return get_text_from_pdf(uploaded_file)
83
+ return ""
84
+
85
+ def get_text_from_txt(uploaded_file):
86
+ return uploaded_file.read().decode("utf-8")
87
+
88
+ def get_text_from_doc(uploaded_file):
89
+ doc = docx.Document(uploaded_file)
90
+ return "\n".join([para.text for para in doc.paragraphs])
91
+
92
+ def get_text_from_pdf(uploaded_file):
93
+ reader = PdfFileReader(io.BytesIO(uploaded_file.read()))
94
+ text = ""
95
+ for page_num in range(reader.getNumPages()):
96
+ text += reader.getPage(page_num).extract_text()
97
+ return text
98
+
99
+
100
+ def qa_from_transcripts(Transcript : str):
101
+ Prompt = st.text_area("Prompt")
102
+ Transcript = st.text_area("Transcript")
103
+ Tasks = "\n\n".join(st.multiselect("Tasks", options = ["Task 1", "Task 2", "Task 3"]))
104
+ if st.button("QA from transcripts"):
105
+ response = requests.post(os.getenv("QA_TRANSCRIPT_ENDPOINT", "http://127.0.0.1:5000/transcript") ,
106
+ json = {
107
+ "prompt": Prompt,
108
+ "transcript" : Transcript or "",
109
+ "tasks": Tasks or [],
110
+ })
111
+ st.success(response.json())
112
+ return
113
+
114
+ def create_tasks_action_from_uploaded_call_transcript(Transcript : str):
115
+
116
+ if st.button("create_tasks"):
117
+ response = requests.post(os.getenv("QA_TRANSCRIPT_ENDPOINT", "http://127.0.0.1:5000/tasks/from_transcript") , json = {"transcript" : Transcript})
118
+ st.session_state.tasks = st.success(response.json())
119
+ return
120
+ if st.session_state.get('tasks'):
121
+ task = st.selectbox("Select a task", st.session_state.tasks)
122
+ task_matchmaking(task)
123
+
124
+ def task_matchmaking(task : str):
125
+ cols = st.columns(2)
126
+ with cols[0]:
127
+ st.markdown("### Task matchmaking")
128
+ with cols[1]:
129
+ st.multiselect("People", ["Alice", "Bob", "Charlie"])
130
+ if st.button("Assign"):
131
+ st.success("Task assigned")