Spaces:
Runtime error
Runtime error
Rodolfo Torres
commited on
Commit
•
97c4064
1
Parent(s):
83f4a9b
Enable news, other fixes
Browse files- README.md +2 -2
- main.py +54 -53
- requirements.txt +3 -2
- static/index.html +43 -2
- static/js/app.js +158 -25
- static/json/prompts-en.json +2 -2
README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1 |
---
|
2 |
-
title:
|
3 |
emoji: 🐨
|
4 |
colorFrom: blue
|
5 |
colorTo: purple
|
@@ -12,7 +12,7 @@ license: mit
|
|
12 |
|
13 |
**Intel® oneAPI Hackathon 2023: The LLM Challenge**
|
14 |
|
15 |
-
Live Demo - https://
|
16 |
|
17 |
Blog - https://medium.com/@roaltopo/unleashing-textual-understanding-with-scanudoc-f2e12499ae11
|
18 |
|
|
|
1 |
---
|
2 |
+
title: ScanUDoc
|
3 |
emoji: 🐨
|
4 |
colorFrom: blue
|
5 |
colorTo: purple
|
|
|
12 |
|
13 |
**Intel® oneAPI Hackathon 2023: The LLM Challenge**
|
14 |
|
15 |
+
Live Demo - https://roaltopo-scan-u-doc.hf.space
|
16 |
|
17 |
Blog - https://medium.com/@roaltopo/unleashing-textual-understanding-with-scanudoc-f2e12499ae11
|
18 |
|
main.py
CHANGED
@@ -1,25 +1,19 @@
|
|
1 |
-
from
|
2 |
-
t_ini = time()
|
3 |
-
from fastapi import FastAPI, UploadFile, File
|
4 |
from fastapi.staticfiles import StaticFiles
|
5 |
from fastapi.responses import FileResponse
|
6 |
-
#from fastapi.middleware.cors import CORSMiddleware
|
7 |
from typing import Optional
|
8 |
from transformers import pipeline
|
9 |
from pydantic import BaseModel
|
10 |
from fastapi.responses import JSONResponse
|
11 |
from io import BytesIO
|
12 |
import PyPDF2
|
|
|
13 |
|
14 |
-
print('End loading libraries: ', round(time()-t_ini))
|
15 |
-
t_ini = time()
|
16 |
model_name = "roaltopo/scan-u-doc_question-answer"
|
17 |
qa_pipeline = pipeline(
|
18 |
"question-answering",
|
19 |
model=model_name,
|
20 |
)
|
21 |
-
print('End loading model: ', round(time()-t_ini))
|
22 |
-
t_ini = time()
|
23 |
|
24 |
app = FastAPI()
|
25 |
|
@@ -36,73 +30,80 @@ class QuestionInfo(BaseModel):
|
|
36 |
|
37 |
@app.post("/store_text/{uuid}")
|
38 |
async def store_text(uuid: str, text_info: TextInfo):
|
39 |
-
|
40 |
-
|
41 |
-
|
42 |
-
|
43 |
-
|
44 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
45 |
|
46 |
-
|
|
|
|
|
|
|
|
|
47 |
|
48 |
# Ruta para cargar un archivo
|
49 |
@app.post("/upload_file/{uuid}")
|
50 |
async def upload_file(uuid: str, file: UploadFile = File(...)):
|
51 |
try:
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
text_storage[uuid] = {
|
80 |
'text': extracted_text,
|
81 |
}
|
82 |
|
83 |
return JSONResponse(content={'success': True})
|
|
|
84 |
except Exception as e:
|
85 |
-
return JSONResponse(content={"message": f"Error
|
86 |
|
87 |
@app.post("/answer_question/{uuid}")
|
88 |
async def answer_question(uuid: str, question_info: QuestionInfo):
|
89 |
-
#text_id = question_info.text_id
|
90 |
question = question_info.question
|
91 |
|
92 |
# Verifica si el texto con el ID existe en el diccionario
|
93 |
if uuid not in text_storage:
|
94 |
return {'error': 'Text not found'}
|
95 |
|
96 |
-
# Implementa la lógica de procesamiento de la pregunta aquí
|
97 |
-
# En este ejemplo, simplemente devuelve una respuesta fija
|
98 |
-
#print(type(text_storage[text_id]), text_storage[text_id]['text'])
|
99 |
-
#response = "El texto original es: " + text_storage[text_id]['text']
|
100 |
-
|
101 |
-
#return {'response': response}
|
102 |
-
#return qa_pipeline(question=question, context=text_storage[text_id]['text'])
|
103 |
r = qa_pipeline(question=question, context=text_storage[uuid]['text'], top_k=10)
|
104 |
-
#print(r)
|
105 |
-
#print('-----------------------------')
|
106 |
return r[0]
|
107 |
|
108 |
|
|
|
1 |
+
from fastapi import FastAPI, UploadFile, File, HTTPException
|
|
|
|
|
2 |
from fastapi.staticfiles import StaticFiles
|
3 |
from fastapi.responses import FileResponse
|
|
|
4 |
from typing import Optional
|
5 |
from transformers import pipeline
|
6 |
from pydantic import BaseModel
|
7 |
from fastapi.responses import JSONResponse
|
8 |
from io import BytesIO
|
9 |
import PyPDF2
|
10 |
+
from newspaper import Article
|
11 |
|
|
|
|
|
12 |
model_name = "roaltopo/scan-u-doc_question-answer"
|
13 |
qa_pipeline = pipeline(
|
14 |
"question-answering",
|
15 |
model=model_name,
|
16 |
)
|
|
|
|
|
17 |
|
18 |
app = FastAPI()
|
19 |
|
|
|
30 |
|
31 |
@app.post("/store_text/{uuid}")
|
32 |
async def store_text(uuid: str, text_info: TextInfo):
|
33 |
+
try:
|
34 |
+
url = text_info.html_url.strip() if text_info.html_url else None
|
35 |
+
if url:
|
36 |
+
print('url:', url)
|
37 |
+
article = Article(url)
|
38 |
+
article.download()
|
39 |
+
article.parse()
|
40 |
+
text = f'{article.title}\n{article.text}'
|
41 |
+
elif text_info.text:
|
42 |
+
text = text_info.text
|
43 |
+
else:
|
44 |
+
raise HTTPException(status_code=400, detail="Invalid Option: 'url' or 'text' required in text_info.")
|
45 |
+
|
46 |
+
# Store information in the in-memory dictionary
|
47 |
+
text_storage[uuid] = {
|
48 |
+
'text': text,
|
49 |
+
'url': text_info.html_url
|
50 |
+
}
|
51 |
|
52 |
+
return {'success': True}
|
53 |
+
except Exception as e:
|
54 |
+
error_message = f"Error: {str(e)}"
|
55 |
+
print(error_message)
|
56 |
+
raise HTTPException(status_code=500, detail="Internal Server Error: An unexpected error occurred.")
|
57 |
|
58 |
# Ruta para cargar un archivo
|
59 |
@app.post("/upload_file/{uuid}")
|
60 |
async def upload_file(uuid: str, file: UploadFile = File(...)):
|
61 |
try:
|
62 |
+
file_extension = file.filename.split('.')[-1].lower()
|
63 |
+
|
64 |
+
if file_extension == 'pdf':
|
65 |
+
content = await file.read()
|
66 |
+
stream = BytesIO(content)
|
67 |
+
reader = PyPDF2.PdfReader(stream)
|
68 |
+
|
69 |
+
extracted_text = ''
|
70 |
+
|
71 |
+
for page_num in range(len(reader.pages)):
|
72 |
+
page = reader.pages[page_num]
|
73 |
+
tmp = page.extract_text()
|
74 |
+
tmp = tmp.replace('\n', ' ')
|
75 |
+
tmp = tmp.replace(' ', ' ')
|
76 |
+
tmp = tmp.replace('. ', '.\n')
|
77 |
+
extracted_text += tmp
|
78 |
+
if len(extracted_text) > 4000:
|
79 |
+
extracted_text = extracted_text[:4000]
|
80 |
+
break
|
81 |
+
|
82 |
+
elif file_extension == 'txt':
|
83 |
+
content = await file.read()
|
84 |
+
extracted_text = content.decode('utf-8')
|
85 |
+
|
86 |
+
else:
|
87 |
+
raise ValueError("Unsupported file format.")
|
88 |
+
|
89 |
text_storage[uuid] = {
|
90 |
'text': extracted_text,
|
91 |
}
|
92 |
|
93 |
return JSONResponse(content={'success': True})
|
94 |
+
|
95 |
except Exception as e:
|
96 |
+
return JSONResponse(content={"message": f"Error while uploading the file: {e}"}, status_code=500)
|
97 |
|
98 |
@app.post("/answer_question/{uuid}")
|
99 |
async def answer_question(uuid: str, question_info: QuestionInfo):
|
|
|
100 |
question = question_info.question
|
101 |
|
102 |
# Verifica si el texto con el ID existe en el diccionario
|
103 |
if uuid not in text_storage:
|
104 |
return {'error': 'Text not found'}
|
105 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
106 |
r = qa_pipeline(question=question, context=text_storage[uuid]['text'], top_k=10)
|
|
|
|
|
107 |
return r[0]
|
108 |
|
109 |
|
requirements.txt
CHANGED
@@ -6,5 +6,6 @@ intel_extension_for_pytorch==2.0.100
|
|
6 |
torch==2.0.1
|
7 |
transformers==4.29.2
|
8 |
pydantic==2.4.2
|
9 |
-
pypdf2==3.0
|
10 |
-
python-multipart==0.*
|
|
|
|
6 |
torch==2.0.1
|
7 |
transformers==4.29.2
|
8 |
pydantic==2.4.2
|
9 |
+
pypdf2==3.0.*
|
10 |
+
python-multipart==0.*
|
11 |
+
newspaper3k==0.*
|
static/index.html
CHANGED
@@ -26,6 +26,8 @@
|
|
26 |
<link rel="icon" type="image/png" sizes="16x16" href="fav/favicon-16x16.png">
|
27 |
<link rel="manifest" href="fav/site.webmanifest">
|
28 |
<link rel="mask-icon" href="fav/safari-pinned-tab.svg" color="#5bbad5">
|
|
|
|
|
29 |
</head>
|
30 |
<body>
|
31 |
|
@@ -99,7 +101,13 @@
|
|
99 |
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{{button_close_modal}"></button>
|
100 |
</div>
|
101 |
<div class="modal-body">
|
102 |
-
<
|
|
|
|
|
|
|
|
|
|
|
|
|
103 |
</div>
|
104 |
<div class="modal-footer">
|
105 |
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{button_close_modal}}</button>
|
@@ -117,8 +125,17 @@
|
|
117 |
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{{button_close_modal}"></button>
|
118 |
</div>
|
119 |
<div class="modal-body">
|
|
|
|
|
|
|
|
|
120 |
<form id="file-form" enctype="multipart/form-data">
|
121 |
-
<
|
|
|
|
|
|
|
|
|
|
|
122 |
</form>
|
123 |
</div>
|
124 |
<div class="modal-footer">
|
@@ -129,6 +146,30 @@
|
|
129 |
</div>
|
130 |
</div>
|
131 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
132 |
<header class="hide-section">
|
133 |
<div class="container">
|
134 |
<div class="row">
|
|
|
26 |
<link rel="icon" type="image/png" sizes="16x16" href="fav/favicon-16x16.png">
|
27 |
<link rel="manifest" href="fav/site.webmanifest">
|
28 |
<link rel="mask-icon" href="fav/safari-pinned-tab.svg" color="#5bbad5">
|
29 |
+
<link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.css">
|
30 |
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.js"></script>
|
31 |
</head>
|
32 |
<body>
|
33 |
|
|
|
101 |
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{{button_close_modal}"></button>
|
102 |
</div>
|
103 |
<div class="modal-body">
|
104 |
+
<div class="alert alert-info" role="alert">
|
105 |
+
Please enter a text of maximum 4000 characters.
|
106 |
+
</div>
|
107 |
+
<textarea id="textArea" class="form-control" rows="4" maxlength="4000"></textarea>
|
108 |
+
<div class="mt-2">
|
109 |
+
<span id="charCount">4000</span> characters remaining
|
110 |
+
</div>
|
111 |
</div>
|
112 |
<div class="modal-footer">
|
113 |
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{button_close_modal}}</button>
|
|
|
125 |
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{{button_close_modal}"></button>
|
126 |
</div>
|
127 |
<div class="modal-body">
|
128 |
+
<div class="alert alert-info" role="alert">
|
129 |
+
You can upload a PDF or TXT file, maximum 1MB in size.<br>
|
130 |
+
Only the first 4000 characters of the text will be processed.
|
131 |
+
</div>
|
132 |
<form id="file-form" enctype="multipart/form-data">
|
133 |
+
<div class="input-group mb-3">
|
134 |
+
<div class="custom-file">
|
135 |
+
<input type="file" class="custom-file-input" id="fileInput" name="file" accept=".pdf,.txt">
|
136 |
+
<label class="custom-file-label" for="fileInput">Choose file</label>
|
137 |
+
</div>
|
138 |
+
</div>
|
139 |
</form>
|
140 |
</div>
|
141 |
<div class="modal-footer">
|
|
|
146 |
</div>
|
147 |
</div>
|
148 |
|
149 |
+
<div class="modal fade" tabindex="-1" id="modalUrl">
|
150 |
+
<div class="modal-dialog">
|
151 |
+
<div class="modal-content">
|
152 |
+
<div class="modal-header">
|
153 |
+
<h5 class="modal-title">Enter the Webpage URL</h5>
|
154 |
+
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="{{button_close_modal}"></button>
|
155 |
+
</div>
|
156 |
+
<div class="modal-body">
|
157 |
+
<div class="alert alert-info" role="alert">
|
158 |
+
You can input a URL from a news website.<br>Note that with other types of websites, the functionality may not work as effectively.
|
159 |
+
</div>
|
160 |
+
<div class="form-group">
|
161 |
+
<label for="url">URL:</label>
|
162 |
+
<input type="text" class="form-control" id="url" value="">
|
163 |
+
</div>
|
164 |
+
</div>
|
165 |
+
<div class="modal-footer">
|
166 |
+
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{button_close_modal}}</button>
|
167 |
+
<button type="button" class="btn btn-primary" id="sendButton3">Send</button>
|
168 |
+
</div>
|
169 |
+
</div>
|
170 |
+
</div>
|
171 |
+
</div>
|
172 |
+
|
173 |
<header class="hide-section">
|
174 |
<div class="container">
|
175 |
<div class="row">
|
static/js/app.js
CHANGED
@@ -595,13 +595,27 @@ function hideChat() {
|
|
595 |
}
|
596 |
|
597 |
// Agrega el evento para el botón "Enviar"
|
598 |
-
|
|
|
|
|
599 |
var textData = {
|
600 |
text: $('#textArea').val(),
|
601 |
-
pdf: null,
|
602 |
-
html_url: null
|
603 |
};
|
604 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
605 |
// Realiza una llamada POST al endpoint /store_text
|
606 |
$.ajax({
|
607 |
type: "POST",
|
@@ -609,41 +623,147 @@ document.getElementById('sendButton').addEventListener('click', function () {
|
|
609 |
data: JSON.stringify(textData),
|
610 |
contentType: "application/json",
|
611 |
success: function (data) {
|
|
|
|
|
|
|
|
|
612 |
$('#textArea').val('');
|
613 |
// Cierra el modal después de enviar el texto
|
614 |
textModal.hide();
|
615 |
displayChat(chatId);
|
616 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
617 |
});
|
618 |
});
|
619 |
|
620 |
$('#sendButton2').click(function (evt) {
|
621 |
-
|
622 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
623 |
|
624 |
-
|
625 |
-
|
626 |
-
|
627 |
-
|
628 |
-
|
629 |
-
|
630 |
-
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
-
|
637 |
-
|
638 |
-
|
639 |
-
|
640 |
-
|
641 |
-
|
642 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
643 |
});
|
644 |
|
645 |
|
646 |
|
|
|
647 |
$(document).delegate(".start-chat", "click", function () {
|
648 |
chatId = $(this).attr("data-index");
|
649 |
if (chatId == 0) {
|
@@ -656,6 +776,11 @@ $(document).delegate(".start-chat", "click", function () {
|
|
656 |
keyboard: false
|
657 |
});
|
658 |
textModal.show();
|
|
|
|
|
|
|
|
|
|
|
659 |
}
|
660 |
//console.log(chatId);
|
661 |
//displayChat($(this).attr("data-index"));
|
@@ -1474,4 +1599,12 @@ $(document).ready(function () {
|
|
1474 |
localStorage.setItem('text-talk-settings', JSON.stringify(settings));
|
1475 |
$('#modalConfig').modal('hide');
|
1476 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1477 |
});
|
|
|
595 |
}
|
596 |
|
597 |
// Agrega el evento para el botón "Enviar"
|
598 |
+
$('#sendButton').click(function (evt) {
|
599 |
+
evt.preventDefault();
|
600 |
+
|
601 |
var textData = {
|
602 |
text: $('#textArea').val(),
|
|
|
|
|
603 |
};
|
604 |
|
605 |
+
// Configurar la posición de Toastr en la parte superior
|
606 |
+
toastr.options.positionClass = 'toast-top-center';
|
607 |
+
|
608 |
+
// Verificar si la variable de texto está vacía
|
609 |
+
if (textData.text.trim() === '') {
|
610 |
+
toastr.error("Error: Text cannot be empty.");
|
611 |
+
return;
|
612 |
+
}
|
613 |
+
|
614 |
+
// Deshabilitar el botón y agregar un spinner
|
615 |
+
var sendButton = $('#sendButton');
|
616 |
+
sendButton.prop('disabled', true);
|
617 |
+
sendButton.html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Sending...');
|
618 |
+
|
619 |
// Realiza una llamada POST al endpoint /store_text
|
620 |
$.ajax({
|
621 |
type: "POST",
|
|
|
623 |
data: JSON.stringify(textData),
|
624 |
contentType: "application/json",
|
625 |
success: function (data) {
|
626 |
+
// Habilitar el botón nuevamente
|
627 |
+
sendButton.prop('disabled', false);
|
628 |
+
sendButton.html('Send');
|
629 |
+
|
630 |
$('#textArea').val('');
|
631 |
// Cierra el modal después de enviar el texto
|
632 |
textModal.hide();
|
633 |
displayChat(chatId);
|
634 |
+
},
|
635 |
+
error: function (xhr, status, error) {
|
636 |
+
// Verificar si hay un código de error del backend
|
637 |
+
if (xhr.status === 400 || xhr.status === 500) {
|
638 |
+
toastr.error(`Error: ${xhr.status} - ${error}`);
|
639 |
+
} else {
|
640 |
+
toastr.error("Error: Connection refused. Please try again later.");
|
641 |
+
}
|
642 |
+
|
643 |
+
// Habilitar el botón nuevamente
|
644 |
+
sendButton.prop('disabled', false);
|
645 |
+
sendButton.html('Send');
|
646 |
+
}
|
647 |
});
|
648 |
});
|
649 |
|
650 |
$('#sendButton2').click(function (evt) {
|
651 |
+
evt.preventDefault();
|
652 |
+
var formData = new FormData($('#file-form')[0]);
|
653 |
+
var sendButton = $('#sendButton2');
|
654 |
+
|
655 |
+
// Configurar la posición de Toastr en la parte superior
|
656 |
+
toastr.options.positionClass = 'toast-top-center';
|
657 |
+
|
658 |
+
var fileInput = $('#fileInput')[0];
|
659 |
+
var fileSize = fileInput.files[0].size; // Tamaño en bytes
|
660 |
+
var maxSize = 1*1024*1024; // 1MB en bytes
|
661 |
+
|
662 |
+
// Validar el tamaño del archivo
|
663 |
+
if (fileSize > maxSize) {
|
664 |
+
toastr.error('Error: File size exceeds 1MB limit.');
|
665 |
+
return;
|
666 |
+
}
|
667 |
+
|
668 |
+
// Deshabilitar el botón y agregar un spinner
|
669 |
+
sendButton.prop('disabled', true);
|
670 |
+
sendButton.html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Uploading...');
|
671 |
+
|
672 |
+
$.ajax({
|
673 |
+
url: `/upload_file/${uuid}`,
|
674 |
+
type: 'POST',
|
675 |
+
data: formData,
|
676 |
+
async: false,
|
677 |
+
cache: false,
|
678 |
+
contentType: false,
|
679 |
+
processData: false,
|
680 |
+
success: function (data) {
|
681 |
+
$('#fileInput').val('');
|
682 |
+
// Habilitar el botón nuevamente
|
683 |
+
sendButton.prop('disabled', false);
|
684 |
+
sendButton.html('Send');
|
685 |
+
|
686 |
+
// Cierra el modal después de enviar el texto
|
687 |
+
textModal.hide();
|
688 |
+
displayChat(chatId);
|
689 |
+
},
|
690 |
+
error: function (xhr, status, error) {
|
691 |
+
// Mostrar mensaje de error con Toastr
|
692 |
+
toastr.error('Error uploading the file');
|
693 |
+
|
694 |
+
// Habilitar el botón nuevamente
|
695 |
+
sendButton.prop('disabled', false);
|
696 |
+
sendButton.html('Send');
|
697 |
+
}
|
698 |
+
});
|
699 |
+
});
|
700 |
|
701 |
+
|
702 |
+
$('#sendButton3').click(function () {
|
703 |
+
var textData = {
|
704 |
+
html_url: $('#url').val(),
|
705 |
+
};
|
706 |
+
|
707 |
+
// Configurar la posición de Toastr en la parte superior
|
708 |
+
toastr.options.positionClass = 'toast-top-center';
|
709 |
+
|
710 |
+
var sendButton = $('#sendButton3');
|
711 |
+
|
712 |
+
// Verificar si la variable de texto está vacía
|
713 |
+
if (textData.html_url.trim() === '') {
|
714 |
+
toastr.error("Error: URL cannot be empty.");
|
715 |
+
return;
|
716 |
+
}
|
717 |
+
|
718 |
+
// Validar la URL
|
719 |
+
var urlRegex = new RegExp('^(https?:\\/\\/)?'+
|
720 |
+
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+
|
721 |
+
'((\\d{1,3}\\.){3}\\d{1,3}))'+
|
722 |
+
'(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+
|
723 |
+
'(\\?[;&a-z\\d%_.~+=-]*)?'+
|
724 |
+
'(\\#[-a-z\\d_]*)?$','i');
|
725 |
+
if (!urlRegex.test(textData.html_url)) {
|
726 |
+
toastr.error("Error: Invalid URL.");
|
727 |
+
return;
|
728 |
+
}
|
729 |
+
|
730 |
+
// Deshabilitar el botón y agregar un spinner
|
731 |
+
sendButton.prop('disabled', true);
|
732 |
+
sendButton.html('<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Sending...');
|
733 |
+
|
734 |
+
// Realiza una llamada POST al endpoint /store_text
|
735 |
+
$.ajax({
|
736 |
+
type: "POST",
|
737 |
+
url: `/store_text/${uuid}`,
|
738 |
+
data: JSON.stringify(textData),
|
739 |
+
contentType: "application/json",
|
740 |
+
success: function (data) {
|
741 |
+
$('#url').val('');
|
742 |
+
// Habilitar el botón nuevamente
|
743 |
+
sendButton.prop('disabled', false);
|
744 |
+
sendButton.html('Send');
|
745 |
+
|
746 |
+
// Cierra el modal después de enviar el texto
|
747 |
+
textModal.hide();
|
748 |
+
displayChat(chatId);
|
749 |
+
},
|
750 |
+
error: function (xhr, status, error) {
|
751 |
+
if (xhr.status === 0) {
|
752 |
+
toastr.error('Error: Connection refused. Please try again later.');
|
753 |
+
} else if (xhr.status === 400 || xhr.status === 500) {
|
754 |
+
toastr.error(`Error: ${xhr.status} - ${error}`);
|
755 |
+
}
|
756 |
+
|
757 |
+
// Habilitar el botón nuevamente
|
758 |
+
sendButton.prop('disabled', false);
|
759 |
+
sendButton.html('Send');
|
760 |
+
}
|
761 |
+
});
|
762 |
});
|
763 |
|
764 |
|
765 |
|
766 |
+
|
767 |
$(document).delegate(".start-chat", "click", function () {
|
768 |
chatId = $(this).attr("data-index");
|
769 |
if (chatId == 0) {
|
|
|
776 |
keyboard: false
|
777 |
});
|
778 |
textModal.show();
|
779 |
+
} else if (chatId == 2) {
|
780 |
+
textModal = new bootstrap.Modal(document.getElementById('modalUrl'), {
|
781 |
+
keyboard: false
|
782 |
+
});
|
783 |
+
textModal.show();
|
784 |
}
|
785 |
//console.log(chatId);
|
786 |
//displayChat($(this).attr("data-index"));
|
|
|
1599 |
localStorage.setItem('text-talk-settings', JSON.stringify(settings));
|
1600 |
$('#modalConfig').modal('hide');
|
1601 |
});
|
1602 |
+
|
1603 |
+
// Maneja el conteo de caracteres
|
1604 |
+
$('#textArea').on('input', function () {
|
1605 |
+
var maxLength = 4000;
|
1606 |
+
var currentLength = $(this).val().length;
|
1607 |
+
var remaining = maxLength - currentLength;
|
1608 |
+
$('#charCount').text(remaining);
|
1609 |
+
});
|
1610 |
});
|
static/json/prompts-en.json
CHANGED
@@ -17,7 +17,7 @@
|
|
17 |
"widget_name": "{{widget_name_2}}",
|
18 |
"image": "img/icon-file.svg",
|
19 |
"welcome_message": "Welcome! Feel free to ask any questions about the selected text. I'm here to provide you with insightful answers.",
|
20 |
-
"description": "
|
21 |
"display_welcome_message": true,
|
22 |
"chat_minlength": 2,
|
23 |
"chat_maxlength": 1000,
|
@@ -29,7 +29,7 @@
|
|
29 |
"widget_name": "{{widget_name_3}}",
|
30 |
"image": "img/icon-webpage.svg",
|
31 |
"welcome_message": "Welcome! Feel free to ask any questions about the selected text. I'm here to provide you with insightful answers.",
|
32 |
-
"description": "
|
33 |
"display_welcome_message": true,
|
34 |
"chat_minlength": 3,
|
35 |
"chat_maxlength": 1000,
|
|
|
17 |
"widget_name": "{{widget_name_2}}",
|
18 |
"image": "img/icon-file.svg",
|
19 |
"welcome_message": "Welcome! Feel free to ask any questions about the selected text. I'm here to provide you with insightful answers.",
|
20 |
+
"description": "Our mission is to simplify text processing and enhance information retrieval using cutting-edge LLM models. Explore our project on <a href=\"https://github.com/roaltopo/scan-u-doc\">GitHub</a>.",
|
21 |
"display_welcome_message": true,
|
22 |
"chat_minlength": 2,
|
23 |
"chat_maxlength": 1000,
|
|
|
29 |
"widget_name": "{{widget_name_3}}",
|
30 |
"image": "img/icon-webpage.svg",
|
31 |
"welcome_message": "Welcome! Feel free to ask any questions about the selected text. I'm here to provide you with insightful answers.",
|
32 |
+
"description": "Our mission is to simplify text processing and enhance information retrieval using cutting-edge LLM models. Explore our project on <a href=\"https://github.com/roaltopo/scan-u-doc\">GitHub</a>.",
|
33 |
"display_welcome_message": true,
|
34 |
"chat_minlength": 3,
|
35 |
"chat_maxlength": 1000,
|