Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -1,563 +1,69 @@
|
|
1 |
import streamlit as st
|
2 |
-
|
3 |
-
from chat_client import chat
|
4 |
-
from google_function import leggi_gmail
|
5 |
-
from google_function import scrivi_bozza_gmail
|
6 |
-
from google_function import leggi_calendario_google
|
7 |
-
from google_function import connetti_google
|
8 |
-
from google_function import crea_documento_google
|
9 |
import time
|
10 |
-
import
|
11 |
-
|
12 |
-
from sentence_transformers import SentenceTransformer
|
13 |
-
import requests
|
14 |
-
from langchain_community.vectorstores import Chroma
|
15 |
-
from langchain_community.embeddings import HuggingFaceEmbeddings
|
16 |
-
import json
|
17 |
-
from googlesearch import search
|
18 |
-
from bs4 import BeautifulSoup
|
19 |
-
import PyPDF2
|
20 |
-
import pytesseract
|
21 |
from PIL import Image
|
22 |
-
from
|
23 |
-
import
|
24 |
-
from streamlit_javascript import st_javascript
|
25 |
-
import datetime
|
26 |
-
from openai import OpenAI
|
27 |
-
|
28 |
-
load_dotenv()
|
29 |
-
EFFETTUA_LOGIN_GOOGLE = os.getenv('EFFETTUA_LOGIN_GOOGLE')=="1"
|
30 |
-
URL_APP_SCRIPT = os.getenv('URL_APP_SCRIPT')
|
31 |
-
URL_PROMPT = URL_APP_SCRIPT + '?IdFoglio=1cLw9q70BsPmxMBj9PIzgXtq6sm3X-GVBVnOB5wE8jr8'
|
32 |
-
URL_DOCUMENTI = URL_APP_SCRIPT + '?IdSecondoFoglio=1cLw9q70BsPmxMBj9PIzgXtq6sm3X-GVBVnOB5wE8jr8'
|
33 |
-
SYSTEM_PROMPT = ["Sei BonsiAI e mi aiuterai nelle mie richieste (Parla in ITALIANO)", "Esatto, sono BonsiAI. Di cosa hai bisogno?"]
|
34 |
-
CHAT_BOTS = {
|
35 |
-
"Mixtral 8x7B v0.1": {
|
36 |
-
"model": "mistralai/Mixtral-8x7B-Instruct-v0.1",
|
37 |
-
"description": "Un modello avanzato di chatbot con architettura 8x7B sviluppato da Mistral AI. Supporta fino a 30 pagine di input e costa zero",
|
38 |
-
"pagine_contesto": 30,
|
39 |
-
"richiede_api_key": False
|
40 |
-
},
|
41 |
-
"Mistral 7B v0.2": {
|
42 |
-
"model": "mistralai/Mistral-7B-Instruct-v0.2",
|
43 |
-
"description": "Una versione più leggera del modello Mistral, con architettura 7B, sviluppato da Mistral AI. Supporta fino a 8 pagine di input e costa zero",
|
44 |
-
"pagine_contesto": 8,
|
45 |
-
"richiede_api_key": False
|
46 |
-
},
|
47 |
-
"Gpt 3.5 Turbo": {
|
48 |
-
"model": "gpt-3.5-turbo",
|
49 |
-
"description": "Una versione ottimizzata e performante del modello GPT-3.5 di OpenAI. Supporta 16 Pagine di input e costa 2$ ogni 1000 Pagine",
|
50 |
-
"pagine_contesto": 16,
|
51 |
-
"richiede_api_key": True
|
52 |
-
},
|
53 |
-
"Gpt 4 Turbo": {
|
54 |
-
"model": "gpt-4-turbo",
|
55 |
-
"description": "Una versione avanzata e potenziata del famoso modello GPT-4 di OpenAI, ottimizzata per prestazioni superiori. Supporta fino a 120 Pagine di input e costa 30$ ogni 1000 Pagine",
|
56 |
-
"pagine_contesto": 120,
|
57 |
-
"richiede_api_key": True
|
58 |
-
},
|
59 |
-
"Gpt 4-o": {
|
60 |
-
"model": "gpt-4o",
|
61 |
-
"description": "L'ultimissima versione di GPT! Supporta fino a 120 Pagine di input e costa 20$ ogni 1000 Pagine (meno di GPT 4 Turbo)",
|
62 |
-
"pagine_contesto": 120,
|
63 |
-
"richiede_api_key": True
|
64 |
-
}
|
65 |
-
}
|
66 |
-
option_personalizzata = {'Personalizzata': {'systemRole': 'Tu sei BONSI AI, il mio assistente personale della scuola superiore del Bonsignori. Aiutami in base alle mie esigenze',
|
67 |
-
'systemStyle': 'Firmati sempre come BONSI AI. (scrivi in italiano)',
|
68 |
-
'instruction': '',
|
69 |
-
'tipo': '',
|
70 |
-
'RAG': False}
|
71 |
-
}
|
72 |
-
option_leggiemail = {'Leggi Gmail': {'systemRole': 'Tu sei BONSI AI, il mio assistente personale della scuola superiore del Bonsignori. Effettua l operazione richiesta sulla base delle seguenti email: ',
|
73 |
-
'systemStyle': 'Firmati sempre come BONSI AI. (scrivi in italiano)',
|
74 |
-
'instruction': '',
|
75 |
-
'tipo': 'EMAIL',
|
76 |
-
'RAG': False}
|
77 |
-
}
|
78 |
-
option_leggicalendar = {'Leggi Calendar': {'systemRole': 'Tu sei BONSI AI, il mio assistente personale della scuola superiore del Bonsignori. Effettua l operazione richiesta sulla base dei seguenti eventi di calendario: ',
|
79 |
-
'systemStyle': 'Firmati sempre come BONSI AI. (scrivi in italiano)',
|
80 |
-
'instruction': '',
|
81 |
-
'tipo': 'CALENDAR',
|
82 |
-
'RAG': False}
|
83 |
-
}
|
84 |
-
# ----------------------------------------------------------- Interfaccia --------------------------------------------------------------------
|
85 |
-
st.set_page_config(page_title="Bonsi A.I.", page_icon="🏫")
|
86 |
-
|
87 |
-
def init_state() :
|
88 |
-
if "messages" not in st.session_state:
|
89 |
-
st.session_state.messages = []
|
90 |
-
|
91 |
-
if "temp" not in st.session_state:
|
92 |
-
st.session_state.temp = 0.8
|
93 |
-
|
94 |
-
if "history" not in st.session_state:
|
95 |
-
st.session_state.history = [SYSTEM_PROMPT]
|
96 |
-
|
97 |
-
if "top_k" not in st.session_state:
|
98 |
-
st.session_state.top_k = 5
|
99 |
-
|
100 |
-
if "repetion_penalty" not in st.session_state :
|
101 |
-
st.session_state.repetion_penalty = 1
|
102 |
-
|
103 |
-
if "api_key" not in st.session_state :
|
104 |
-
st.session_state.api_key = ""
|
105 |
-
|
106 |
-
if "chat_bot" not in st.session_state :
|
107 |
-
st.session_state.chat_bot = "Mixtral 8x7B v0.1"
|
108 |
-
|
109 |
-
if 'loaded_data' not in st.session_state:
|
110 |
-
st.session_state.loaded_data = False
|
111 |
-
|
112 |
-
if "split" not in st.session_state:
|
113 |
-
st.session_state.split = 30
|
114 |
-
|
115 |
-
if "enable_history" not in st.session_state:
|
116 |
-
st.session_state.enable_history = True
|
117 |
-
|
118 |
-
if "audio_bytes" not in st.session_state:
|
119 |
-
st.session_state.audio_bytes = False
|
120 |
-
|
121 |
-
if "cerca_online" not in st.session_state:
|
122 |
-
st.session_state.cerca_online = False
|
123 |
-
|
124 |
-
if "numero_siti" not in st.session_state:
|
125 |
-
st.session_state.numero_siti = 3
|
126 |
-
|
127 |
-
if "suddividi_siti" not in st.session_state:
|
128 |
-
st.session_state.suddividi_siti = 1
|
129 |
-
|
130 |
-
if "cerca_dominio" not in st.session_state:
|
131 |
-
st.session_state.cerca_dominio = False
|
132 |
-
|
133 |
-
if "numero_generazioni" not in st.session_state:
|
134 |
-
st.session_state.numero_generazioni = 1
|
135 |
-
|
136 |
-
if "numero_elementi" not in st.session_state:
|
137 |
-
st.session_state.numero_elementi = 5
|
138 |
-
|
139 |
-
if "data_inizio" not in st.session_state:
|
140 |
-
st.session_state.data_inizio = None
|
141 |
-
|
142 |
-
if "data_inizio" not in st.session_state:
|
143 |
-
st.session_state.data_inizio = None
|
144 |
-
|
145 |
-
if "testo_documenti" not in st.session_state:
|
146 |
-
st.session_state.testo_documenti = ''
|
147 |
-
|
148 |
-
if "uploaded_files" not in st.session_state:
|
149 |
-
st.session_state.uploaded_files = None
|
150 |
-
|
151 |
-
if "client" not in st.session_state:
|
152 |
-
st.session_state.client = None
|
153 |
-
|
154 |
-
if "urls" not in st.session_state:
|
155 |
-
st.session_state.urls = [""] * 5
|
156 |
-
|
157 |
-
if "creds" not in st.session_state:
|
158 |
-
st.session_state.creds = None
|
159 |
-
|
160 |
-
if "login_effettuato" not in st.session_state:
|
161 |
-
st.session_state.login_effettuato = False
|
162 |
-
|
163 |
-
if "ultimo_messaggio" not in st.session_state:
|
164 |
-
st.session_state.ultimo_messaggio = ""
|
165 |
-
|
166 |
-
if "tutti_messaggi" not in st.session_state:
|
167 |
-
st.session_state.tutti_messaggi = ""
|
168 |
-
|
169 |
-
if "tbs_options" not in st.session_state:
|
170 |
-
st.session_state.tbs_options = {
|
171 |
-
"Sempre": "0",
|
172 |
-
"Ultimo anno": "qdr:y",
|
173 |
-
"Ultimo mese": "qdr:m",
|
174 |
-
"Ultima settimana": "qdr:w",
|
175 |
-
"Ultimo giorno": "qdr:d"
|
176 |
-
}
|
177 |
-
|
178 |
-
if not st.session_state.loaded_data and (st.session_state.login_effettuato == True or EFFETTUA_LOGIN_GOOGLE == False):
|
179 |
-
place=st.empty()
|
180 |
-
place=st.empty()
|
181 |
-
with place:
|
182 |
-
with st.status("Caricamento in corso...", expanded=True) as status:
|
183 |
-
st.write("Inizializzazione Ambiente")
|
184 |
-
time.sleep(1)
|
185 |
-
st.write("Inizializzazione Prompt")
|
186 |
-
URL_REDIRECT = os.getenv('URL_REDIRECT')
|
187 |
-
options = {}
|
188 |
-
if URL_REDIRECT != "http://localhost:8501/":
|
189 |
-
options = requests.get(URL_PROMPT).json()
|
190 |
-
st.write("Inizializzazione Documenti")
|
191 |
-
documenti = {}
|
192 |
-
if URL_REDIRECT != "http://localhost:8501/":
|
193 |
-
documenti = requests.get(URL_DOCUMENTI).json()
|
194 |
-
st.session_state.options = {**option_personalizzata, **options}
|
195 |
-
if EFFETTUA_LOGIN_GOOGLE:
|
196 |
-
st.session_state.options.update(option_leggiemail)
|
197 |
-
st.session_state.options.update(option_leggicalendar)
|
198 |
-
st.session_state.documenti = documenti
|
199 |
-
st.session_state.loaded_data = True
|
200 |
-
status.update(label="Caricamento Completato", state="complete", expanded=False)
|
201 |
-
place.empty()
|
202 |
|
203 |
-
|
204 |
-
|
205 |
-
|
206 |
-
|
207 |
-
|
208 |
-
|
209 |
-
for page_num in range(len(pdf_reader.pages)):
|
210 |
-
page = pdf_reader.pages[page_num]
|
211 |
-
text += page.extract_text()
|
212 |
-
else:
|
213 |
try:
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
218 |
-
|
219 |
-
|
220 |
-
|
221 |
-
|
222 |
-
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
st.session_state.selected_option = st.session_state.options.get(st.session_state.selected_option_key, {})
|
243 |
-
|
244 |
-
if st.session_state.options.get(st.session_state.selected_option_key, {})["tipo"]=='DOCUMENTO':
|
245 |
-
st.session_state.selected_documento_key = st.selectbox('Documento', list(st.session_state.documenti.keys()))
|
246 |
-
st.session_state.selected_documento = st.session_state.documenti.get(st.session_state.selected_documento_key, {})
|
247 |
-
st.session_state.instruction = st.session_state.selected_documento.get('instruction', '')['Testo']
|
248 |
-
else:
|
249 |
-
st.session_state.instruction = st.session_state.selected_option.get('instruction', '')
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
st.session_state.systemRole = st.session_state.selected_option.get('systemRole', '')
|
254 |
-
st.session_state.systemRole = st.text_area("Descrizione", st.session_state.systemRole, help='Ruolo del chatbot e descrizione dell\'azione che deve svolgere')
|
255 |
-
st.session_state.systemStyle = st.session_state.selected_option.get('systemStyle', '')
|
256 |
-
st.session_state.systemStyle = st.text_area("Stile", st.session_state.systemStyle, help='Descrizione dello stile utilizzato per generare il testo')
|
257 |
-
if st.session_state.selected_option["tipo"]=='EMAIL':
|
258 |
-
st.session_state.numero_elementi = st.slider(label="Numero Email", min_value=1, max_value=100, value=10)
|
259 |
-
st.session_state.data_inizio = st.date_input("Email dal", value=datetime.date.today()-datetime.timedelta(days=7), format='DD/MM/YYYY')
|
260 |
-
st.session_state.data_fine = st.date_input("Email al", value=datetime.date.today(), format='DD/MM/YYYY')
|
261 |
-
if st.session_state.selected_option["tipo"]=='CALENDAR':
|
262 |
-
st.session_state.numero_elementi = st.slider(label="Numero Eventi Calendario", min_value=1, max_value=100, value=10)
|
263 |
-
st.session_state.data_inizio = st.date_input("Eventi dal", value=datetime.date.today(), format='DD/MM/YYYY')
|
264 |
-
st.session_state.data_fine = st.date_input("Eventi al", value=datetime.date.today()+datetime.timedelta(days=7), format='DD/MM/YYYY')
|
265 |
-
st.session_state.rag_enabled = st.session_state.selected_option.get('tipo', '')=='RAG'
|
266 |
-
if st.session_state.selected_option_key == 'Decreti':
|
267 |
-
st.session_state.top_k = st.slider(label="Documenti da ricercare", min_value=1, max_value=20, value=4, disabled=not st.session_state.rag_enabled)
|
268 |
-
st.session_state.decreti_escludere = st.multiselect(
|
269 |
-
'Decreti da escludere',
|
270 |
-
['23.10.2 destinazione risorse residue pnrr DGR 1051-2023_Destinazione risorse PNRR Duale.pdf', '23.10.25 accompagnatoria Circolare Inail assicurazione.pdf', '23.10.26 circolare Inail assicurazione.pdf', '23.10.3 FAQ in attesa di avviso_.pdf', '23.11.2 avviso 24_24 Decreto 17106-2023 Approvazione Avviso IeFP 2023-2024.pdf', '23.5.15 decreto linee inclusione x enti locali.pdf', '23.6.21 Circolare+esplicativa+DGR+312-2023.pdf', '23.7.3 1° Decreto R.L. 23_24 .pdf', '23.9 Regolamento_prevenzione_bullismo_e_cyberbullismo__Centro_Bonsignori.pdf', '23.9.1 FAQ inizio anno formativo.pdf', '23.9.15 DECRETO VERIFICHE AMMINISTR 15-09-23.pdf', '23.9.4 modifica decreto GRS.pdf', '23.9.8 Budget 23_24.pdf', '24.10.2022 DECRETO loghi N.15176.pdf', 'ALLEGATO C_Scheda Supporti al funzionamento.pdf', 'ALLEGATO_ B_ Linee Guida.pdf', 'ALLEGATO_A1_PEI_INFANZIA.pdf', 'ALLEGATO_A2_PEI_PRIMARIA.pdf', 'ALLEGATO_A3_PEI_SEC_1_GRADO.pdf', 'ALLEGATO_A4_PEI_SEC_2_GRADO.pdf', 'ALLEGATO_C_1_Tabella_Fabbisogni.pdf', 'Brand+Guidelines+FSE+.pdf', 'Decreto 20797 del 22-12-2023_Aggiornamento budget PNRR.pdf', 'Decreto 20874 del 29-12-2023 Avviso IeFP PNRR 2023-2024_file unico.pdf'],
|
271 |
-
[])
|
272 |
-
st.session_state.uploaded_files = st.file_uploader("Importa file", accept_multiple_files=True)
|
273 |
-
st.session_state.testo_documenti = ''
|
274 |
-
for uploaded_file in st.session_state.uploaded_files:
|
275 |
-
text_doc = read_text_from_file(uploaded_file)
|
276 |
-
st.session_state.testo_documenti += text_doc
|
277 |
-
print(st.session_state.testo_documenti)
|
278 |
-
st.markdown("---")
|
279 |
-
st.markdown("# Ricerca Online")
|
280 |
-
st.session_state.cerca_online = st.toggle("Attivata", value=False)
|
281 |
-
with st.popover("Siti Specifici", disabled=not st.session_state.cerca_online,use_container_width=True):
|
282 |
-
st.markdown("#### Inserisci Siti Web ")
|
283 |
-
st.session_state.cerca_dominio = st.toggle("Cerca nel dominio", value=False, help="Se disattivo, cerca SOLO all'interno dell'url per esempio se digito www.ansa.it, cerca solo nella HOME PAGE di ansa, altrimenti cerca all'interno di tutto il DOMINIO ansa.it")
|
284 |
-
for i in range(5):
|
285 |
-
if (i<2) or ((i>1) and (st.session_state.urls[i-2] != "")):
|
286 |
-
st.session_state.urls[i] = st.text_input(f"URL Sito {i+1}", placeholder='Sito Web...', help='è possibile specificare anche il link di un video Youtube, in tal caso verrà restituita la trascrizione del video')
|
287 |
-
st.session_state.selected_tbs = st.selectbox("Periodo:", list(st.session_state.tbs_options.keys()), disabled=(not st.session_state.cerca_online) or (st.session_state.urls[0]!="" and not st.session_state.cerca_dominio))
|
288 |
-
st.session_state.tbs_value = st.session_state.tbs_options[st.session_state.selected_tbs]
|
289 |
-
st.session_state.numero_siti = st.slider(label="Risultati", min_value = 1, max_value=20, value=3, disabled=(not st.session_state.cerca_online) or (st.session_state.urls[0]!="" and not st.session_state.cerca_dominio))
|
290 |
-
st.session_state.suddividi_siti = st.slider(label="Scomponi Ricerca", min_value = 1, max_value=10, value=1, disabled=(not st.session_state.cerca_online) or (st.session_state.urls[0]!="" and not st.session_state.cerca_dominio))
|
291 |
-
st.markdown("---")
|
292 |
-
|
293 |
-
def model_settings():
|
294 |
-
st.markdown("# Modello")
|
295 |
-
st.session_state.chat_bot = st.sidebar.selectbox('Tipo', list(CHAT_BOTS.keys()))
|
296 |
-
if CHAT_BOTS[st.session_state.chat_bot]["richiede_api_key"] == True:
|
297 |
-
st.session_state.api_key = st.text_input('Api Key', type = 'password', label_visibility='collapsed', placeholder='Inserisci la chiave API')
|
298 |
-
st.session_state.client = OpenAI(api_key=st.session_state.api_key)
|
299 |
-
print('xxxxxxx')
|
300 |
-
st.write(CHAT_BOTS[st.session_state.chat_bot]["description"])
|
301 |
-
st.session_state.split = st.slider(label="Pagine Suddivisione", min_value=1, max_value=CHAT_BOTS[st.session_state.chat_bot]["pagine_contesto"], value=CHAT_BOTS[st.session_state.chat_bot]["pagine_contesto"], help='Se il documento ha 100 pagine e suddivido per 20 pagine elaborerà la risposta 5 volte. Più alto è il numero e meno volte elaborerà ma la risposta sarà più imprecisa')
|
302 |
-
st.session_state.numero_generazioni = st.slider(label="Generazioni", min_value = 1, max_value=10, value=1)
|
303 |
-
st.session_state.enable_history = st.toggle("Storico Messaggi", value=True)
|
304 |
-
st.session_state.temp = st.slider(label="Creatività", min_value=0.0, max_value=1.0, step=0.1, value=0.9)
|
305 |
-
st.session_state.max_tokens = st.slider(label="Lunghezza Output", min_value = 2, max_value=4096, step= 32, value=1024)
|
306 |
-
st.markdown("---")
|
307 |
-
|
308 |
-
def export_settings():
|
309 |
-
st.markdown("# Esportazione")
|
310 |
-
st.session_state.export_type = st.selectbox('Tipologia', ('Non Esportare', 'Google Documenti', 'Bozza Email'), help='Seleziona la tipologia di esportazione del testo generato')
|
311 |
-
st.session_state.export_all = st.toggle("Considera tutte le chat", value=False)
|
312 |
-
if st.button("Esporta", type="primary", use_container_width=True):
|
313 |
-
esporta_testo(st.session_state.export_type, st.session_state.export_all)
|
314 |
-
st.markdown("---")
|
315 |
-
|
316 |
-
with st.sidebar:
|
317 |
-
retrieval_settings()
|
318 |
-
model_settings()
|
319 |
-
if EFFETTUA_LOGIN_GOOGLE:
|
320 |
-
export_settings()
|
321 |
-
st.markdown("""> **Creato da Matteo Bergamelli **""")
|
322 |
-
|
323 |
-
def header() :
|
324 |
-
st.title("Bonsi A.I.", anchor=False)
|
325 |
-
with st.expander("Cos'è BonsiAI?"):
|
326 |
-
st.info("""BonsiAI Chat è un ChatBot personalizzato basato su un database vettoriale, funziona secondo il principio della Generazione potenziata da Recupero (RAG).
|
327 |
-
La sua funzione principale ruota attorno alla gestione di un ampio repository di documenti BonsiAI e fornisce agli utenti risposte in linea con le loro domande.
|
328 |
-
Questo approccio garantisce una risposta più precisa sulla base della richiesta degli utenti.""")
|
329 |
-
|
330 |
-
def chat_box() :
|
331 |
-
for message in st.session_state.messages:
|
332 |
-
with st.chat_message(message["role"]):
|
333 |
-
st.markdown(message["content"])
|
334 |
-
|
335 |
-
def formattaPrompt(prompt, systemRole, systemStyle, instruction):
|
336 |
-
if st.session_state.cerca_online:
|
337 |
-
systemRole += '. Ti ho fornito una lista di materiali nelle instruction. Devi rispondere sulla base delle informazioni fonrnite!'
|
338 |
-
input_text = f'''
|
339 |
-
{{
|
340 |
-
"input": {{
|
341 |
-
"role": "system",
|
342 |
-
"content": "{systemRole}",
|
343 |
-
"style": "{systemStyle} "
|
344 |
-
}},
|
345 |
-
"messages": [
|
346 |
-
{{
|
347 |
-
"role": "instructions",
|
348 |
-
"content": "{instruction} ({systemStyle})"
|
349 |
-
}},
|
350 |
-
{{
|
351 |
-
"role": "user",
|
352 |
-
"content": "{prompt}"
|
353 |
-
}}
|
354 |
-
]
|
355 |
-
}}
|
356 |
-
'''
|
357 |
-
return input_text
|
358 |
-
|
359 |
-
def gen_augmented_prompt(prompt, top_k) :
|
360 |
-
links = ""
|
361 |
-
embedding = HuggingFaceEmbeddings(model_name="sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2")
|
362 |
-
db = Chroma(persist_directory='./DB_Decreti', embedding_function=embedding)
|
363 |
-
docs = db.similarity_search(prompt, k=top_k)
|
364 |
-
links = []
|
365 |
-
context = ''
|
366 |
-
NomeCartellaOriginariaDB = 'Documenti_2\\'
|
367 |
-
for doc in docs:
|
368 |
-
testo = doc.page_content.replace('\n', ' ')
|
369 |
-
context += testo + '\n\n\n'
|
370 |
-
reference = doc.metadata["source"].replace(NomeCartellaOriginariaDB, '') + ' (Pag. ' + str(doc.metadata["page"]) + ')'
|
371 |
-
links.append((reference, testo))
|
372 |
-
return context, links
|
373 |
-
|
374 |
-
def get_search_results_int(url):
|
375 |
-
result = {'title': '', 'description': '', 'url': '', 'body': ''}
|
376 |
-
try:
|
377 |
-
if "www.youtube.com" in url:
|
378 |
-
video_id = url.split("=")[1]
|
379 |
-
title = 'Video Youtube'
|
380 |
-
description = ''
|
381 |
-
transcript = YouTubeTranscriptApi.get_transcript(video_id)
|
382 |
-
body_content = " ".join([segment["text"] for segment in transcript])
|
383 |
-
print(video_id)
|
384 |
-
print(body_content)
|
385 |
-
result = {'title': title, 'description': body_content, 'url': url, 'body': body_content}
|
386 |
else:
|
387 |
-
|
388 |
-
|
389 |
-
|
390 |
-
|
391 |
-
|
392 |
-
|
393 |
-
|
394 |
-
|
395 |
-
|
396 |
-
|
397 |
-
|
398 |
-
|
399 |
-
|
400 |
-
|
401 |
-
|
402 |
-
|
403 |
-
if st.session_state.cerca_dominio:
|
404 |
-
for url in search(query + ' site:' + dominio, num=top_k, stop=top_k, tbs=st.session_state.tbs_value):
|
405 |
-
results.append(get_search_results_int(url))
|
406 |
-
else:
|
407 |
-
results.append(get_search_results_int(dominio))
|
408 |
-
else:
|
409 |
-
for url in search(query, num=top_k, stop=top_k, tbs=st.session_state.tbs_value):
|
410 |
-
results.append(get_search_results_int(url))
|
411 |
-
return results
|
412 |
-
|
413 |
-
def gen_online_prompt(prompt, top_k) :
|
414 |
-
links = []
|
415 |
-
context = ''
|
416 |
-
if st.session_state.suddividi_siti > 1:
|
417 |
-
prompt_suddivisione = f'''Genera un elenco PUNTATO di {st.session_state.suddividi_siti} PAROLE CHIAVE in ITALIANO ottimizzate per il WEB e l'indicizzazione SEO.
|
418 |
-
Attenzione, restituisci solo le KEYWORD e non scrivere nulla prima o dopo!
|
419 |
-
Genera le PAROLE CHIAVE a partire da questo argomento, mi raccomando devono essere un elenco PUNTATO in ITALIANO: "{prompt}" '''
|
420 |
-
chat_stream = generate_chat_stream(prompt_suddivisione)
|
421 |
-
risposta = stream_handler(chat_stream, None)
|
422 |
-
sottoricerche = risposta.strip().split('\n')
|
423 |
-
for sottoricerca in sottoricerche:
|
424 |
-
with st.spinner('Sottoricerca: ' + sottoricerca):
|
425 |
-
results = get_search_results(sottoricerca, top_k)
|
426 |
-
for i, result in enumerate(results, start=1):
|
427 |
-
st.toast(result['title'], icon = '🗞️' )
|
428 |
-
context += result['title'] + '\n' + result['description'] + '\n' + '\n\n' + result['body'].replace('\n','.') + '\n\n------------------------------------------------------------'
|
429 |
-
links.append((str(i) + '. ' + result['title'], result['description'] + '\n\n' + result['url']))
|
430 |
-
else:
|
431 |
-
results = get_search_results(prompt, top_k)
|
432 |
-
for i, result in enumerate(results, start=1):
|
433 |
-
st.toast(result['title'])
|
434 |
-
context += result['title'] + '\n' + result['description'] + '\n' + '\n\n' + result['body'].replace('\n','.') + '\n\n------------------------------------------------------------'
|
435 |
-
links.append((str(i) + '. ' + result['title'], result['description'] + '\n\n' + result['url']))
|
436 |
-
if context == '':
|
437 |
-
context = "Non sono state trovate informazioni sul Web in merito all'argomento specificato. Riprova con un altra ricerca o modifica i parametri"
|
438 |
-
return context, links
|
439 |
-
|
440 |
-
def generate_chat_stream(prompt):
|
441 |
-
chat_stream = chat(prompt, st.session_state.history,chat_client=CHAT_BOTS[st.session_state.chat_bot]["model"],
|
442 |
-
temperature=st.session_state.temp, max_new_tokens=st.session_state.max_tokens, client_openai = st.session_state.client)
|
443 |
-
return chat_stream
|
444 |
-
|
445 |
-
def inserisci_istruzioni(prompt_originale):
|
446 |
-
links = []
|
447 |
-
if st.session_state.cerca_online:
|
448 |
-
with st.spinner("Ricerca Online...."):
|
449 |
-
time.sleep(1)
|
450 |
-
st.session_state.instruction, links = gen_online_prompt(prompt=prompt_originale, top_k=st.session_state.numero_siti)
|
451 |
-
if st.session_state.rag_enabled :
|
452 |
-
with st.spinner("Ricerca nei Decreti...."):
|
453 |
-
time.sleep(1)
|
454 |
-
st.session_state.instruction, links = gen_augmented_prompt(prompt=prompt_originale, top_k=st.session_state.top_k)
|
455 |
-
if st.session_state.selected_option["tipo"]=='EMAIL':
|
456 |
-
with st.spinner("Ricerca nelle Email...."):
|
457 |
-
time.sleep(1)
|
458 |
-
st.session_state.instruction, links = leggi_gmail(max_results=st.session_state.numero_elementi, data_inizio = st.session_state.data_inizio, data_fine = st.session_state.data_fine)
|
459 |
-
if st.session_state.selected_option["tipo"]=='CALENDAR':
|
460 |
-
with st.spinner("Ricerca nel Calendario...."):
|
461 |
-
time.sleep(1)
|
462 |
-
st.session_state.instruction, links = leggi_calendario_google(max_results=st.session_state.numero_elementi, data_inizio = st.session_state.data_inizio, data_fine = st.session_state.data_fine)
|
463 |
-
with st.spinner("Generazione in corso...") :
|
464 |
-
time.sleep(1)
|
465 |
-
#st.session_state.instruction = instruction_originale + '\n----------------------------------------------\n' + st.session_state.instruction
|
466 |
-
return links
|
467 |
-
|
468 |
-
def stream_handler(chat_stream, placeholder):
|
469 |
-
full_response = ''
|
470 |
-
for chunk in chat_stream :
|
471 |
-
if CHAT_BOTS[st.session_state.chat_bot]["model"][:3] == 'gpt':
|
472 |
-
if chunk.choices[0].delta and chunk.choices[0].delta.content:
|
473 |
-
full_response += chunk.choices[0].delta.content
|
474 |
else:
|
475 |
-
|
476 |
-
|
477 |
-
|
478 |
-
|
479 |
-
|
480 |
-
|
481 |
-
|
482 |
-
|
483 |
-
def show_source(links) :
|
484 |
-
with st.expander("Mostra fonti") :
|
485 |
-
for link in links:
|
486 |
-
reference, testo = link
|
487 |
-
st.info('##### ' + reference.replace('_', ' ') + '\n\n'+ testo)
|
488 |
-
|
489 |
-
def split_text(text, chunk_size):
|
490 |
-
testo_suddiviso = []
|
491 |
-
if text == '':
|
492 |
-
text = ' '
|
493 |
-
if chunk_size < 100:
|
494 |
-
chunk_size = 60000
|
495 |
-
for i in range(0, len(text), chunk_size):
|
496 |
-
testo_suddiviso.append(text[i:i+chunk_size])
|
497 |
-
return testo_suddiviso
|
498 |
-
|
499 |
-
init_state()
|
500 |
-
if not st.session_state.login_effettuato and EFFETTUA_LOGIN_GOOGLE:
|
501 |
-
connetti_google()
|
502 |
-
|
503 |
-
if st.session_state.login_effettuato or not EFFETTUA_LOGIN_GOOGLE:
|
504 |
-
st_javascript("localStorage.removeItem('token');")
|
505 |
-
init_state()
|
506 |
-
sidebar()
|
507 |
-
header()
|
508 |
-
chat_box()
|
509 |
-
|
510 |
-
if prompt := st.chat_input("Chatta con BonsiAI..."):
|
511 |
-
prompt_originale = prompt
|
512 |
-
links = inserisci_istruzioni(prompt_originale)
|
513 |
-
st.session_state.instruction+= ' \n\n' + st.session_state.testo_documenti
|
514 |
-
instruction_suddivise = split_text(st.session_state.instruction, st.session_state.split*2000)
|
515 |
-
ruolo_originale = st.session_state.systemRole
|
516 |
-
ruoli_divisi = ruolo_originale.split("&&")
|
517 |
-
parte=1
|
518 |
-
i=1
|
519 |
-
risposta_completa = ''
|
520 |
-
full_response = ''
|
521 |
-
errore_generazione = False
|
522 |
-
for ruolo_singolo in ruoli_divisi:
|
523 |
-
for instruction_singola in instruction_suddivise:
|
524 |
-
for numgen in range(1, st.session_state.numero_generazioni+1):
|
525 |
-
if i==1:
|
526 |
-
st.chat_message("user").markdown(prompt_originale + (': Parte ' + str(parte) if i > 1 else ''))
|
527 |
-
i+=1
|
528 |
-
prompt = formattaPrompt(prompt_originale, ruolo_singolo, st.session_state.systemStyle, instruction_singola)
|
529 |
-
print('------------------------------------------------------------------------------------')
|
530 |
-
print(prompt)
|
531 |
-
st.session_state.messages.append({"role": "user", "content": prompt_originale})
|
532 |
-
try:
|
533 |
-
chat_stream = generate_chat_stream(prompt)
|
534 |
-
with st.chat_message("assistant"):
|
535 |
-
placeholder = st.empty()
|
536 |
-
full_response = stream_handler(chat_stream, placeholder)
|
537 |
-
if st.session_state.rag_enabled or st.session_state.cerca_online or st.session_state.selected_option["tipo"]=='EMAIL' or st.session_state.selected_option["tipo"]=='CALENDAR':
|
538 |
-
show_source(links)
|
539 |
-
if st.session_state.options.get(st.session_state.selected_option_key, {})["tipo"]=='DOCUMENTO':
|
540 |
-
with st.expander("Mostra Documento") :
|
541 |
-
st.info('##### ' + st.session_state.selected_documento_key + ' (Parte ' + str(parte) +')'+ '\n\n\n' + instruction_singola)
|
542 |
-
parte+=1
|
543 |
-
st.session_state.messages.append({"role": "assistant", "content": full_response})
|
544 |
-
risposta_completa = risposta_completa + '\n' + full_response
|
545 |
-
except Exception as e:
|
546 |
-
print(str(e))
|
547 |
-
errore_generazione = True
|
548 |
-
if CHAT_BOTS[st.session_state.chat_bot]["model"][:3] == 'gpt':
|
549 |
-
st.error('Inserisci una CHIAVE API valida e controlla il CREDITO residuo: https://platform.openai.com/api-keys')
|
550 |
-
else:
|
551 |
-
st.error('Errore nella generazione riprova o utilizza un altro modello AI')
|
552 |
-
|
553 |
-
if errore_generazione == False:
|
554 |
-
st.session_state.ultimo_messaggio = full_response
|
555 |
-
st.session_state.tutti_messaggi += '\n\n' + full_response
|
556 |
-
if st.session_state.enable_history:
|
557 |
-
st.session_state.history.append([prompt_originale, full_response])
|
558 |
-
else:
|
559 |
-
st.session_state.history.append(['', ''])
|
560 |
-
st.success('Generazione Completata')
|
561 |
-
payload = {"domanda": prompt_originale, "risposta": risposta_completa}
|
562 |
-
json_payload = json.dumps(payload)
|
563 |
-
response = requests.post(URL_APP_SCRIPT, data=json_payload)
|
|
|
1 |
import streamlit as st
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
import time
|
3 |
+
import base64
|
4 |
+
import io
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
from PIL import Image
|
6 |
+
from together import Together
|
7 |
+
import os
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
8 |
|
9 |
+
# Funzione per generare le immagini, con gestione errori e retry dopo 10 secondi
|
10 |
+
def generate_image(prompt, max_retries=5):
|
11 |
+
api_key = os.getenv('API_REPLIACATE')
|
12 |
+
client = Together(api_key = api_key)
|
13 |
+
retries = 0
|
14 |
+
while retries < max_retries:
|
|
|
|
|
|
|
|
|
15 |
try:
|
16 |
+
response = client.images.generate(
|
17 |
+
prompt=prompt,
|
18 |
+
model="black-forest-labs/FLUX.1-schnell-Free",
|
19 |
+
width=960,
|
20 |
+
height=1440,
|
21 |
+
steps=4,
|
22 |
+
n=1,
|
23 |
+
response_format="b64_json"
|
24 |
+
)
|
25 |
+
return response.data # Una lista di oggetti con attributo b64_json
|
26 |
+
except Exception as e:
|
27 |
+
st.error(f"Errore durante la generazione delle immagini: {e}. Riprovo tra 10 secondi...")
|
28 |
+
time.sleep(10)
|
29 |
+
retries += 1
|
30 |
+
st.error("Numero massimo di tentativi raggiunto. Impossibile generare le immagini.")
|
31 |
+
return None
|
32 |
+
|
33 |
+
def generate_images(prompt, num_immagini):
|
34 |
+
for numero in range(num_immagini):
|
35 |
+
images_data = generate_image(prompt)
|
36 |
+
if images_data is not None:
|
37 |
+
for i, img_obj in enumerate(images_data):
|
38 |
+
try:
|
39 |
+
image_bytes = base64.b64decode(img_obj.b64_json)
|
40 |
+
image = Image.open(io.BytesIO(image_bytes))
|
41 |
+
st.image(image, caption="")
|
42 |
+
except Exception as e:
|
43 |
+
st.error(f"Errore nella visualizzazione dell'immagine {i+1}: {e}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
else:
|
45 |
+
st.error("Non è stato possibile generare le immagini. Riprova più tardi.")
|
46 |
+
time.sleep(5)
|
47 |
+
st.success("Immagini generate con successo!")
|
48 |
+
|
49 |
+
def main():
|
50 |
+
st.title("AI Imaging")
|
51 |
+
st.sidebar.header("Impostazioni")
|
52 |
+
stile_default = "Highly detailed, painterly style with a historical yet stylized aesthetic. Rich textures, ornate patterns, and a color palette dominated by imperial gold, deep red, and aged marble tones. Inspired by ancient Roman mosaics, frescoes, and classical sculpture, with a balanced mix of realism and stylization. Elegant, decorative card borders with intricate engravings and antique flourishes. Designed for a tabletop card game, ensuring clarity, readability, and a visually immersive experience."
|
53 |
+
stile_immagine = st.sidebar.text_area("Stile Immagine", stile_default, disabled=False)
|
54 |
+
prompt_input = st.sidebar.text_area("Prompt Immagine")
|
55 |
+
num_immagini = st.sidebar.slider("Variazioni", min_value=1, max_value=6, value=2)
|
56 |
+
submit_button = st.sidebar.button(label="Genera Immagine", type = "primary", use_container_width=True)
|
57 |
+
st.write("Inserisci il **Prompt** (che verrà unito allo stile) e clicca su *Genera Immagine*.")
|
58 |
+
if submit_button:
|
59 |
+
if not prompt_input.strip():
|
60 |
+
st.error("Per favore, inserisci un prompt per l'immagine!")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
61 |
else:
|
62 |
+
# Combiniamo il prompt inserito con lo stile fisso
|
63 |
+
prompt_completo = f"{prompt_input}, {stile_immagine}"
|
64 |
+
|
65 |
+
st.info("Generazione in corso, attendere...")
|
66 |
+
generate_images(prompt_completo, num_immagini)
|
67 |
+
|
68 |
+
if __name__ == "__main__":
|
69 |
+
main()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|