Skip to content

Commit e2bdd19

Browse files
WenjiaoYuepre-commit-ci[bot]lvliang-intel
authored
update faqGen ui response (#1091)
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: lvliang-intel <liang1.lv@intel.com>
1 parent c9088eb commit e2bdd19

File tree

8 files changed

+112
-65
lines changed

8 files changed

+112
-65
lines changed

FaqGen/tests/test_compose_on_gaudi.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ function main() {
169169

170170
validate_microservices
171171
validate_megaservice
172-
validate_frontend
172+
# validate_frontend
173173

174174
stop_docker
175175
echo y | docker system prune

FaqGen/tests/test_compose_on_xeon.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ function main() {
169169

170170
validate_microservices
171171
validate_megaservice
172-
validate_frontend
172+
# validate_frontend
173173

174174
stop_docker
175175
echo y | docker system prune

FaqGen/ui/svelte/.env

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
DOC_BASE_URL = 'http://backend_address:8888/v1/faqgen'
1+
FAQ_BASE_URL = 'http://backend_address:8888/v1/faqgen'

FaqGen/ui/svelte/src/lib/doc.svelte

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@
3838
} else {
3939
currentIdx = index;
4040
if (
41-
(currentIdx === 1 && message !== "") ||
42-
(currentIdx === 2 && $kb_id !== "")
41+
(currentIdx === 2 && message !== "") ||
42+
(currentIdx === 1 && $kb_id !== "")
4343
) {
4444
formModal = true;
4545
} else {
@@ -49,10 +49,10 @@
4949
}
5050
5151
function panelExchange() {
52-
if (currentIdx === 2) {
52+
if (currentIdx === 1) {
5353
kb_id.set("");
5454
dispatch("clearMsg", { status: true });
55-
} else if (currentIdx === 1) {
55+
} else if (currentIdx === 2) {
5656
message = "";
5757
dispatch("clearMsg", { status: true });
5858
}
@@ -152,7 +152,7 @@
152152
type="submit"
153153
data-testid="sum-click"
154154
class="xl:my-12 inline-flex items-center px-5 py-2.5 text-sm font-medium text-center text-white bg-blue-700 mt-2 focus:ring-4 focus:ring-blue-200 dark:focus:ring-blue-900 hover:bg-blue-800"
155-
on:click={() => generateFaq()}
155+
on:click={() => generateFaq()}
156156
>
157157
Generate FAQs
158158
</button>
@@ -165,11 +165,11 @@
165165
/>
166166
{#if currentIdx === 1}
167167
<h3 class="mb-5 text-lg font-normal text-gray-500 dark:text-gray-400">
168-
The current content will be cleared.
168+
The currently uploaded file will be cleared.
169169
</h3>
170170
{:else if currentIdx === 2}
171171
<h3 class="mb-5 text-lg font-normal text-gray-500 dark:text-gray-400">
172-
The currently uploaded file will be cleared.
172+
The current content will be cleared.
173173
</h3>
174174
{/if}
175175

FaqGen/ui/svelte/src/lib/dropFile.svelte

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,30 +15,36 @@
1515
-->
1616

1717
<script lang="ts">
18-
import { Dropzone } from "flowbite-svelte";
19-
import ImgLogo from "./assets/imgLogo.svelte";
20-
import { kb_id } from "./shared/Store.js";
21-
import { fetchKnowledgeBaseId } from "./shared/Network.js";
18+
import { kb_id, uploadFile, uploadFilesName } from "./shared/Store.js";
2219
2320
let uploadInput: HTMLInputElement;
24-
let uploadFileName = '';
25-
21+
let uploadFileName = "";
22+
let displayHint = false;
2623
2724
function handleInput(event: Event) {
2825
const file = (event.target as HTMLInputElement).files![0];
2926
3027
if (!file) return;
3128
29+
// Check if the file size exceeds 2KB (2048 bytes)
30+
if (file.size > 2048) {
31+
displayHint = true;
32+
setTimeout(() => {
33+
displayHint = false;
34+
}, 3000);
35+
return; // Exit the function if the file is too large
36+
}
37+
3238
const reader = new FileReader();
3339
reader.onloadend = async () => {
3440
if (!reader.result) return;
3541
const src = reader.result.toString();
3642
const blob = await fetch(src).then((r) => r.blob());
3743
const fileName = file.name;
44+
uploadFilesName.set(fileName);
45+
kb_id.set(fileName);
46+
uploadFile.set(blob);
3847
uploadFileName = fileName;
39-
const res = await fetchKnowledgeBaseId(blob, fileName);
40-
kb_id.set(res.document_id);
41-
console.log("upload File", $kb_id);
4248
};
4349
reader.readAsDataURL(file);
4450
}
@@ -65,13 +71,18 @@
6571
d="M13 13h3a3 3 0 0 0 0-6h-.025A5.56 5.56 0 0 0 16 6.5 5.5 5.5 0 0 0 5.207 5.021C5.137 5.017 5.071 5 5 5a4 4 0 0 0 0 8h2.167M10 15V6m0 0L8 8m2-2 2 2"
6672
/>
6773
</svg>
68-
{#if uploadFileName === ''}
74+
{#if uploadFileName === ""}
6975
<p class="mb-2 text-sm text-gray-500 dark:text-gray-400">
7076
<span class="font-semibold">Click to upload</span> or drag and drop
7177
</p>
7278
<p class="text-xs text-gray-500 dark:text-gray-400">
7379
PDF, TXT, .Doc and so on
7480
</p>
81+
{#if displayHint}
82+
<p class="text-xs text-red-500 dark:text-red-400">
83+
Maximum upload size is 2KB.
84+
</p>
85+
{/if}
7586
{:else}
7687
<p>{uploadFileName}</p>
7788
{/if}

FaqGen/ui/svelte/src/lib/shared/Network.ts

Lines changed: 57 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -12,50 +12,75 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
import { SSE } from "sse.js";
1615
import { env } from "$env/dynamic/public";
1716

18-
const DOC_BASE_URL = env.DOC_BASE_URL;
17+
const FAQ_BASE_URL = env.FAQ_BASE_URL;
1918

20-
async function fetchPostRes(url, init) {
21-
try {
22-
const response = await fetch(url, init);
23-
if (!response.ok) throw response.status;
24-
return await response.json();
25-
} catch (error) {
26-
console.error("network error: ", error);
27-
return undefined;
19+
export async function fetchTextStream(query: string | Blob, params: string, file: Blob, fileName: string | undefined) {
20+
const url = `${FAQ_BASE_URL}`; // Ensure the URL is constructed correctly
21+
const formData = new FormData();
22+
23+
if (!file) {
24+
file = new Blob([""], { type: "text/plain" });
25+
fileName = "empty.txt";
2826
}
29-
}
3027

31-
export async function fetchKnowledgeBaseId(file: Blob, fileName: string) {
32-
const url = `${DOC_BASE_URL}/doc_upload`;
33-
const formData = new FormData();
34-
formData.append("file", file, fileName);
28+
if (params === "doc_id") {
29+
formData.append("files", file, fileName);
30+
formData.append("messages", query);
31+
} else if (params === "text") {
32+
formData.append("files", file, fileName);
33+
formData.append("messages", query);
34+
}
3535

36-
const init: RequestInit = {
36+
// Initiate the POST request to upload the file
37+
const init = {
3738
method: "POST",
3839
body: formData,
3940
};
4041

41-
return fetchPostRes(url, init);
42-
}
42+
const postResponse = await fetch(url, init);
4343

44-
export async function fetchTextStream(query: string, urlSuffix: string, params: string) {
45-
let payload = {};
46-
let url = "";
47-
if (params === "doc_id") {
48-
payload = { doc_id: query };
49-
url = ``;
50-
} else if (params === "text") {
51-
payload = { messages: query };
52-
url = `${DOC_BASE_URL}`;
44+
if (!postResponse.ok) {
45+
throw new Error(`Error uploading file: ${postResponse.status}`);
5346
}
5447

55-
console.log("url", url);
48+
// Function to create an async iterator for the stream
49+
async function* streamGenerator() {
50+
if (!postResponse.body) {
51+
throw new Error("Response body is null");
52+
}
53+
const reader = postResponse.body.getReader();
54+
const decoder = new TextDecoder("utf-8");
55+
let done, value;
56+
57+
let buffer = ""; // Initialize a buffer
58+
59+
while (({ done, value } = await reader.read())) {
60+
if (done) break;
61+
62+
// Decode chunk and append to buffer
63+
const chunk = decoder.decode(value, { stream: true });
64+
buffer += chunk;
65+
66+
// Use regex to clean and extract data
67+
const cleanedChunks = buffer
68+
.split("\n")
69+
.map((line) => {
70+
// Remove 'data: b' at the start and ' ' at the end
71+
return line.replace(/^data:\s*|^b'|'\s*$/g, "").trim(); // Clean unnecessary characters
72+
})
73+
.filter((line) => line); // Remove empty lines
74+
75+
for (const cleanedChunk of cleanedChunks) {
76+
// Further clean to ensure all unnecessary parts are removed
77+
yield cleanedChunk.replace(/^b'|['"]$/g, ""); // Again clean 'b' and other single or double quotes
78+
}
79+
80+
// If there is an incomplete message in the current buffer, keep it
81+
buffer = buffer.endsWith("\n") ? "" : cleanedChunks.pop() || ""; // Keep the last incomplete part
82+
}
83+
}
5684

57-
return new SSE(url, {
58-
headers: { "Content-Type": "application/json" },
59-
payload: JSON.stringify(payload),
60-
});
85+
return streamGenerator(); // Return the async generator
6186
}

FaqGen/ui/svelte/src/lib/shared/Store.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,7 @@ import { writable } from "svelte/store";
1717
export let kb_id = writable("");
1818

1919
export let loading = writable(false);
20+
21+
export const uploadFile = writable<Blob | null>(null);
22+
23+
export let uploadFilesName = writable("");

FaqGen/ui/svelte/src/routes/+page.svelte

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import Doc from "$lib/doc.svelte";
2020
import Faq from "$lib/faq.svelte";
2121
import { fetchTextStream } from "$lib/shared/Network.js";
22-
import { loading } from "$lib/shared/Store.js";
22+
import { loading, uploadFilesName, uploadFile } from "$lib/shared/Store.js";
2323
import { onMount } from "svelte";
2424
import { scrollToBottom } from "$lib/shared/Utils.js";
2525
@@ -31,28 +31,33 @@
3131
console.log("scrollToDiv", scrollToDiv);
3232
});
3333
34-
let code_output: string = "";
35-
let query: string = "";
36-
let deleteFlag: boolean = false;
37-
3834
const callTextStream = async (
3935
query: string,
4036
urlSuffix: string,
41-
params: string,
37+
params: string
4238
) => {
43-
messages = "";
44-
const eventSource = await fetchTextStream(query, urlSuffix, params);
39+
// Fetch the stream
40+
const eventStream = await fetchTextStream(
41+
query,
42+
params,
43+
$uploadFile,
44+
$uploadFilesName
45+
);
46+
47+
// Process the stream as an async iterator
48+
try {
49+
for await (const chunk of eventStream) {
50+
let Msg = chunk;
51+
console.log('Msg', Msg);
4552
46-
eventSource.addEventListener("message", (e: any) => {
47-
let Msg = e.data;
4853
if (Msg !== "[DONE]") {
4954
let res = JSON.parse(Msg);
5055
let logs = res.ops;
5156
5257
logs.forEach((log: { op: string; path: string; value: any }) => {
5358
if (log.op === "add") {
5459
if (
55-
log.value !== "</s>" &&
60+
log.value !== "<|eot_id|>" &&
5661
log.path.endsWith("/streamed_output/-") &&
5762
log.path.length > "/streamed_output/-".length
5863
) {
@@ -65,8 +70,10 @@
6570
loading.set(false);
6671
scrollToBottom(scrollToDiv);
6772
}
68-
});
69-
eventSource.stream();
73+
}
74+
} catch (error) {
75+
console.error("Error processing the stream:", error);
76+
}
7077
};
7178
7279
async function handleGenerateFaq(e) {

0 commit comments

Comments
 (0)