Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RAG UI Updates #90

Merged
merged 7 commits into from
Nov 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions example/retrieval_qa/retrieval_qa_huggingface_demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
# "HuggingFaceH4/zephyr-7b-beta"
# "meta-llama/Llama-2-7b-chat-hf"
# "mistralai/Mistral-7B-v0.1"
# "databricks/dolly-v2-3b"
# "databricks/dolly-v2-3b"

RETRIEVAL_MODEL = os.getenv("RETRIEVAL_MODEL")


Expand Down Expand Up @@ -55,7 +55,7 @@ def main(**kwargs):
# retrieval, chatbot, and dashboard pykoi components
retriever = RetrievalQA(retrieval_model=retrieval_model, vector_db=vector_db, feedback="rag")
chatbot = Chatbot(None, feedback="rag", is_retrieval=True)
dashboard = Dashboard(RAGDatabase(), feedback="rag")
# dashboard = Dashboard(RAGDatabase(), feedback="rag")

############################################################
# Starting the application and retrieval qa as a component #
Expand All @@ -64,8 +64,7 @@ def main(**kwargs):
app = Application(debug=False, share=False)
app.add_component(retriever)
app.add_component(chatbot)
app.add_component(dashboard)
print("RUNNING APP IN DEMO MODE")
# app.add_component(dashboard)
app.run()


Expand Down
65 changes: 65 additions & 0 deletions pykoi/frontend/dist/assets/index-3b11fb1e.js

Large diffs are not rendered by default.

64 changes: 0 additions & 64 deletions pykoi/frontend/dist/assets/index-6c166968.js

This file was deleted.

1 change: 0 additions & 1 deletion pykoi/frontend/dist/assets/index-761f2ce2.css

This file was deleted.

1 change: 1 addition & 0 deletions pykoi/frontend/dist/assets/index-fc934c27.css

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions pykoi/frontend/dist/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 100 100%22><text y=%22.9em%22 font-size=%2290%22>🎏</text></svg>">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + Svelte</title>
<script type="module" crossorigin src="/assets/index-6c166968.js"></script>
<link rel="stylesheet" href="/assets/index-761f2ce2.css">
<title>pykoi</title>
<script type="module" crossorigin src="/assets/index-3b11fb1e.js"></script>
<link rel="stylesheet" href="/assets/index-fc934c27.css">
</head>
<body>
<div id="app"></div>

</body>
</html>
4 changes: 4 additions & 0 deletions pykoi/frontend/src/assets/CloudArrowUp.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<script>
export let height = 256, width = 256;
</script>
<svg xmlns="http://www.w3.org/2000/svg" width={width} height={height} fill="currentColor" viewBox="0 0 256 256"><path d="M248,128a87.34,87.34,0,0,1-17.6,52.81,8,8,0,1,1-12.8-9.62A71.34,71.34,0,0,0,232,128a72,72,0,0,0-144,0,8,8,0,0,1-16,0,88,88,0,0,1,3.29-23.88C74.2,104,73.1,104,72,104a48,48,0,0,0,0,96H96a8,8,0,0,1,0,16H72A64,64,0,1,1,81.29,88.68,88,88,0,0,1,248,128Zm-90.34-5.66a8,8,0,0,0-11.32,0l-32,32a8,8,0,0,0,11.32,11.32L144,147.31V208a8,8,0,0,0,16,0V147.31l18.34,18.35a8,8,0,0,0,11.32-11.32Z"></path></svg>
2 changes: 1 addition & 1 deletion pykoi/frontend/src/lib/Chatbots/Chat.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<Chatbot feedback={true} {is_retrieval} />
{/if}
{#if feedback === "rag"}
<RAGChatbot feedback={true} {is_retrieval} />
<RAGChatbot feedback={false} {is_retrieval} />
{/if}
{#if feedback === "rank"}
<!-- TODO: Refactor to support ranking with retrieval-->
Expand Down
1 change: 1 addition & 0 deletions pykoi/frontend/src/lib/Chatbots/Components/Answer.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
text-align: left;
padding: 10px;
border: 1px solid var(--black);
width: 100%;
}
.small-button {
margin-left: 10px;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { checkedDocs } from "../../../store";
import { selectAll } from "d3-selection";
import { tooltip } from "../../../utils.js";
import { clickOutside } from "../../../utils.js";

export let documents = [];

Expand Down Expand Up @@ -44,12 +45,18 @@
return text;
}

function handleClickOutside(e) {
e.preventDefault();
console.log('click outside');
expanded = false;
}

$: console.log($checkedDocs);
</script>

<form>
<!-- svelte-ignore a11y-click-events-have-key-events -->
<div class="multiselect">
<div class="multiselect" use:clickOutside on:click_outside={handleClickOutside}>
<div class="selectBox" on:click={toggleCheckboxes}>
<select>
<option>Documents</option>
Expand Down
26 changes: 14 additions & 12 deletions pykoi/frontend/src/lib/Chatbots/RAGChatbot.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -155,17 +155,19 @@
<DownloadModal bind:showModal table="rag_table" />

<div class="ranked-feedback-container">
<div class="instructions">
<h5 class="underline bold">Vote Feedback Instructions</h5>
<p>
Ask a question to receive an answer from the chatbot. If the response is
satisfactory, click on the <span class="inline-button green">👍</span>
button. If the response is not satisfactory, click on the
<span class="inline-button red">👎</span> button.
</p>
<button on:click={handleDownloadClick}>Download Data</button>
</div>
<div class="ranked-chat">
{#if feedback}
<div class="instructions">
<h5 class="underline bold">Vote Feedback Instructions</h5>
<p>
Ask a question to receive an answer from the chatbot. If the response is
satisfactory, click on the <span class="inline-button green">👍</span>
button. If the response is not satisfactory, click on the
<span class="inline-button red">👎</span> button.
</p>
<button on:click={handleDownloadClick}>Download Data</button>
</div>
{/if}
<div class="ranked-chat" style:grid-column={feedback ? "span 1" : "span 2"}>
<section class="chatbox">
<div class="chat-log">
{#each $chatLog as message, index (index)}
Expand Down Expand Up @@ -235,7 +237,7 @@
height: 100vh;
display: grid;
grid-template-columns: 100%;
grid-template-rows: 80% 20%;
grid-template-rows: 65% 35%;
}

.message {
Expand Down
77 changes: 67 additions & 10 deletions pykoi/frontend/src/lib/RAG/RAG.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,33 @@
import Table from "./Components/tanstackTable/Table.svelte";
import { onMount } from "svelte";
import { uploadedFiles, projections } from "../store.js";
import CloudArrowUp from "../../assets/CloudArrowUp.svelte";

let selectedFiles = [];
let indexed = false;
let indexing = false;
async function handleFileChange(event) {
selectedFiles = event.target.files;
event.preventDefault();
let selectedFiles = [];
if (event.dataTransfer) {
if (event.dataTransfer.items) {
// Use DataTransferItemList interface to access the file(s)
[...event.dataTransfer.items].forEach((item, i) => {
// If dropped items aren't files, reject them
if (item.kind === "file") {
const file = item.getAsFile();
selectedFiles.push(file);
}
});
} else {
// Use DataTransfer interface to access the file(s)
[...event.dataTransfer.files].forEach((file, i) => {
selectedFiles.push(file);
});
}
} else {
selectedFiles = event.target.files;
}
const formData = new FormData();
// iterate over selectedFiles and add them to array
for (let i = 0; i < selectedFiles.length; i++) {
Expand Down Expand Up @@ -56,6 +77,12 @@
$projections = embeddingData;
}

function dragOverHandler(event) {
console.log("File(s) in drop zone");
// Prevent default behavior (Prevent file from being opened)
event.preventDefault();
}

onMount(() => {
loadServerData();
});
Expand All @@ -76,18 +103,27 @@
<div class="upload-container">
<div class="upload-box">
<h4>Upload Data</h4>
<br />
<form>
<input type="file" multiple on:change={handleFileChange} />
</form>
<p>These are the files your model will use as context.</p>
<div class="upload-files-container">
<form>
<input type="file" multiple on:change={handleFileChange} />
</form>
<div
class="drop-zone"
on:drop={handleFileChange}
on:dragover={dragOverHandler}
>
<CloudArrowUp height={32} width={32} />
Drag and drop files here
</div>
</div>
{#if indexing && !indexed}
<p>{dots}</p>
{/if}
{#if indexed}
<p>Data Successfully indexed!</p>
{/if}
<p>These are the files your model will use as context.</p>
<p>Currently <strong>pdf</strong>, txt, and md are supported.</p>
<p>Currently pdf, txt, and md are supported.</p>
</div>
</div>
</div>
Expand All @@ -100,6 +136,17 @@
</div>

<style>
.drop-zone {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border: 2px dashed var(--grey);
background-color: var(--lightGrey);
width: 100%;
color: #444;
min-height: 300px;
}
.file-container {
display: grid;
height: calc(100% - var(--headerHeight));
Expand All @@ -123,22 +170,32 @@
.data-grid {
display: grid;
grid-template-columns: 45% 50%;
gap: 0;
gap: 8px;
margin: auto;
max-width: 1200px;
padding-top: 20px;
}

.upload-box {
display: flex;
gap: 10px;
flex-direction: column;
justify-content: center;
align-items: center;
height: 100%;
max-height: 50vh;
margin: auto;
border: 5px dashed var(--grey);
padding: 20px;
border: 1px solid #333;
box-sizing: border-box;
}
.upload-files-container {
display: flex;
flex-direction: column;
gap: 10px;
width: 90%;
}

p {
margin: 0;
}
</style>
20 changes: 20 additions & 0 deletions pykoi/frontend/src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,23 @@ export function tooltip(node, params) {
}
}
}

/** Dispatch event on click outside of node */
export function clickOutside(node) {

const handleClick = event => {
if (node && !node.contains(event.target) && !event.defaultPrevented) {
node.dispatchEvent(
new CustomEvent('click_outside', node)
)
}
}

document.addEventListener('click', handleClick, true);

return {
destroy() {
document.removeEventListener('click', handleClick, true);
}
}
}