Update dependencies and fix import paths

This commit is contained in:
n4ze3m
2024-04-05 20:28:29 +05:30
parent d91d4c4761
commit ac347a3970
43 changed files with 1142 additions and 99 deletions

View File

@@ -7,7 +7,7 @@ import React from "react"
import { useMutation } from "@tanstack/react-query"
import { getPageShareUrl } from "~/services/ollama"
import { cleanUrl } from "~/libs/clean-url"
import { getUserId, saveWebshare } from "~/libs/db"
import { getUserId, saveWebshare } from "@/db"
import { useTranslation } from "react-i18next"
type Props = {

View File

@@ -15,7 +15,7 @@ import {
SquarePen,
ZapIcon
} from "lucide-react"
import { getAllPrompts } from "~/libs/db"
import { getAllPrompts } from "@/db"
import { ShareBtn } from "~/components/Common/ShareBtn"
import { useTranslation } from "react-i18next"
import { OllamaIcon } from "../Icons/Ollama"

View File

@@ -68,12 +68,12 @@ export const SettingsLayout = ({ children }: { children: React.ReactNode }) => {
current={location.pathname}
icon={BrainCircuit}
/>
{/* <LinkComponent
<LinkComponent
href="/settings/knowledge"
name={t("manageKnowledge.title")}
icon={BlocksIcon}
current={location.pathname}
/> */}
/>
<LinkComponent
href="/settings/prompt"
name={t("managePrompts.title")}

View File

@@ -0,0 +1,139 @@
import { Source, createKnowledge } from "@/db/knowledge"
import { defaultEmbeddingModelForRag } from "@/services/ollama"
import { convertToSource } from "@/utils/to-source"
import { useMutation } from "@tanstack/react-query"
import { Modal, Form, Input, Upload, message, UploadFile } from "antd"
import { InboxIcon } from "lucide-react"
import { useTranslation } from "react-i18next"
import PubSub from "pubsub-js"
import { KNOWLEDGE_QUEUE } from "@/queue"
type Props = {
open: boolean
setOpen: React.Dispatch<React.SetStateAction<boolean>>
}
export const AddKnowledge = ({ open, setOpen }: Props) => {
const { t } = useTranslation("knowledge")
const [form] = Form.useForm()
const onUploadHandler = async (data: {
title: string
file: UploadFile[]
}) => {
const defaultEM = await defaultEmbeddingModelForRag()
if (!defaultEM) {
throw new Error(t("noEmbeddingModel"))
}
const source: Source[] = []
for (const file of data.file) {
const data = await convertToSource(file)
source.push(data)
}
const knowledge = await createKnowledge({
embedding_model: defaultEM,
source,
title: data.title
})
return knowledge.id
}
const { mutate: saveKnowledge, isPending: isSaving } = useMutation({
mutationFn: onUploadHandler,
onError: (error) => {
message.error(error.message)
},
onSuccess: async (id) => {
message.success(t("form.success"))
PubSub.publish(KNOWLEDGE_QUEUE, id)
setOpen(false)
}
})
return (
<Modal
title={t("addKnowledge")}
open={open}
footer={null}
onCancel={() => setOpen(false)}>
<Form onFinish={saveKnowledge} form={form} layout="vertical">
<Form.Item
rules={[
{
required: true,
message: t("form.title.required")
}
]}
name="title"
label={t("form.title.label")}>
<Input size="large" placeholder={t("form.title.placeholder")} />
</Form.Item>
<Form.Item
name="file"
label={t("form.uploadFile.label")}
rules={[
{
required: true,
message: t("form.uploadFile.required")
}
]}
getValueFromEvent={(e) => {
if (Array.isArray(e)) {
return e
}
return e?.fileList
}}>
<Upload.Dragger
accept={".pdf, .csv, .txt"}
multiple={true}
maxCount={10}
beforeUpload={(file) => {
const allowedTypes = [
"application/pdf",
// "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"text/csv",
"text/plain"
]
.map((type) => type.toLowerCase())
.join(", ")
if (!allowedTypes.includes(file.type.toLowerCase())) {
message.error(
t("form.uploadFile.uploadError", { allowedTypes })
)
return Upload.LIST_IGNORE
}
return false
}}>
<div className="p-3">
<p className="ant-upload-drag-icon justify-center flex">
<InboxIcon className="h-10 w-10 text-gray-400" />
</p>
<p className="ant-upload-text">
{t("form.uploadFile.uploadText")}
</p>
<p className="ant-upload-hint">
{t("form.uploadFile.uploadHint")}
</p>
</div>
</Upload.Dragger>
</Form.Item>
<Form.Item>
<button
type="submit"
disabled={isSaving}
className="inline-flex w-full text-center justify-center items-center rounded-md border border-transparent bg-black px-2 py-2 text-md font-medium leading-4 text-white shadow-sm hover:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 dark:bg-white dark:text-gray-800 dark:hover:bg-gray-100 dark:focus:ring-gray-500 dark:focus:ring-offset-gray-100 disabled:opacity-50">
{t("form.submit")}
</button>
</Form.Item>
</Form>
</Modal>
)
}

View File

@@ -0,0 +1,51 @@
import { getAllKnowledge } from "@/db/knowledge"
import { useQuery } from "@tanstack/react-query"
import { Dropdown, Tooltip } from "antd"
import { Blocks } from "lucide-react"
import React from "react"
import { useTranslation } from "react-i18next"
export const KnowledgeSelect: React.FC = () => {
const { t } = useTranslation("playground")
const { data } = useQuery({
queryKey: ["getAllKnowledge"],
queryFn: async () => {
const data = await getAllKnowledge("finished")
return data
},
refetchInterval: 1000
})
return (
<Dropdown
menu={{
items:
data?.map((d) => ({
key: d.id,
label: (
<div className="w-52 gap-2 text-lg truncate inline-flex line-clamp-3 items-center dark:border-gray-700">
<div>
<Blocks className="h-6 w-6 text-gray-400" />
</div>
{d.title}
</div>
),
onClick: () => {}
})) || [],
style: {
maxHeight: 500,
overflowY: "scroll"
},
// hidescrollbars: true
className: "no-scrollbar"
}}
placement={"topLeft"}
trigger={["click"]}>
<Tooltip title={t("tooltip.knowledge")}>
<button type="button" className="dark:text-gray-300">
<Blocks className="h-6 w-6" />
</button>
</Tooltip>
</Dropdown>
)
}

View File

@@ -0,0 +1,138 @@
import { useState } from "react"
import { useTranslation } from "react-i18next"
import { AddKnowledge } from "./AddKnowledge"
import {
useMutation,
useQuery,
useQueryClient
} from "@tanstack/react-query"
import { deleteKnowledge, getAllKnowledge } from "@/db/knowledge"
import { Skeleton, Table, Tag, Tooltip, message } from "antd"
import { Trash2 } from "lucide-react"
export const KnowledgeSettings = () => {
const { t } = useTranslation(["knownledge", "common"])
const [open, setOpen] = useState(false)
const queryClient = useQueryClient()
const { data, status } = useQuery({
queryKey: ["fetchAllKnowledge"],
queryFn: () => getAllKnowledge(),
refetchInterval: 1000
})
const { mutate: deleteKnowledgeMutation, isPending: isDeleting } =
useMutation({
mutationFn: deleteKnowledge,
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: ["fetchAllKnowledge"]
})
message.success(t("deleteSuccess"))
},
onError: (error) => {
message.error(error.message)
}
})
return (
<div>
<div>
{/* Add new model button */}
<div className="mb-6">
<div className="-ml-4 -mt-2 flex flex-wrap items-center justify-end sm:flex-nowrap">
<div className="ml-4 mt-2 flex-shrink-0">
<button
onClick={() => setOpen(true)}
className="inline-flex items-center rounded-md border border-transparent bg-black px-2 py-2 text-md font-medium leading-4 text-white shadow-sm hover:bg-gray-800 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 dark:bg-white dark:text-gray-800 dark:hover:bg-gray-100 dark:focus:ring-gray-500 dark:focus:ring-offset-gray-100 disabled:opacity-50">
{t("addBtn")}
</button>
</div>
</div>
</div>
{status === "pending" && <Skeleton paragraph={{ rows: 8 }} />}
{status === "success" && (
<Table
columns={[
{
title: t("columns.title"),
dataIndex: "title",
key: "title"
},
{
title: t("columns.status"),
dataIndex: "status",
key: "status",
render: (text: string) => (
<Tag color="blue">{t(`status.${text}`)}</Tag>
)
},
{
title: t("columns.embeddings"),
dataIndex: "embedding_model",
key: "embedding_model"
},
{
title: t("columns.createdAt"),
dataIndex: "createdAt",
key: "createdAt",
render: (text: number) => new Date(text).toLocaleString()
},
{
title: t("columns.action"),
key: "action",
render: (text: string, record: any) => (
<div className="flex gap-4">
<Tooltip title={t("tooltip.delete")}>
<button
disabled={isDeleting}
onClick={() => {
if (window.confirm(t("confirm.delete"))) {
deleteKnowledgeMutation(record.id)
}
}}
className="text-red-500 dark:text-red-400">
<Trash2 className="w-5 h-5" />
</button>
</Tooltip>
</div>
)
}
]}
expandable={{
expandedRowRender: (record) => (
<Table
pagination={false}
columns={[
{
title: t("expandedColumns.name"),
key: "filename",
dataIndex: "filename"
},
{
title: t("expandedColumns.type"),
key: "type",
dataIndex: "type"
}
]}
dataSource={record.source}
locale={{
emptyText: t("common:noData")
}}
/>
),
defaultExpandAllRows: false
}}
bordered
dataSource={data}
rowKey={(record) => `${record.name}-${record.id}`}
/>
)}
</div>
<AddKnowledge open={open} setOpen={setOpen} />
</div>
)
}

View File

@@ -4,7 +4,7 @@ import React from "react"
import useDynamicTextareaSize from "~/hooks/useDynamicTextareaSize"
import { toBase64 } from "~/libs/to-base64"
import { useMessageOption } from "~/hooks/useMessageOption"
import { Checkbox, Dropdown, Switch, Tooltip } from "antd"
import { Checkbox, Dropdown, Select, Switch, Tooltip } from "antd"
import { Image } from "antd"
import { useSpeechRecognition } from "~/hooks/useSpeechRecognition"
import { useWebUI } from "~/store/webui"
@@ -12,6 +12,7 @@ import { defaultEmbeddingModelForRag } from "~/services/ollama"
import { ImageIcon, MicIcon, StopCircleIcon, X } from "lucide-react"
import { getVariable } from "~/utils/select-varaible"
import { useTranslation } from "react-i18next"
import { KnowledgeSelect } from "../Knowledge/KnowledgeSelect"
type Props = {
dropedFile: File | undefined
@@ -249,6 +250,7 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
</Tooltip>
</div>
<div className="flex !justify-end gap-3">
<KnowledgeSelect />
<Tooltip title={t("tooltip.speechToText")}>
<button
type="button"
@@ -273,6 +275,7 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
)}
</button>
</Tooltip>
<Tooltip title={t("tooltip.uploadImage")}>
<button
type="button"
@@ -284,7 +287,7 @@ export const PlaygroundForm = ({ dropedFile }: Props) => {
}`}>
<ImageIcon className="h-5 w-5" />
</button>
</Tooltip>
</Tooltip>
{!isSending ? (
<Dropdown.Button
htmlType="submit"

View File

@@ -18,7 +18,7 @@ import {
getAllPrompts,
savePrompt,
updatePrompt
} from "~/libs/db"
} from "@/db"
export const PromptBody = () => {
const queryClient = useQueryClient()

View File

@@ -1,7 +1,7 @@
import { useQueryClient } from "@tanstack/react-query"
import { useDarkMode } from "~/hooks/useDarkmode"
import { useMessageOption } from "~/hooks/useMessageOption"
import { PageAssitDatabase } from "~/libs/db"
import { PageAssitDatabase } from "@/db"
import { Select } from "antd"
import { SUPPORTED_LANGUAGES } from "~/utils/supporetd-languages"
import { MoonIcon, SunIcon } from "lucide-react"

View File

@@ -3,7 +3,7 @@ import { Form, Input, Skeleton, Table, Tooltip, message } from "antd"
import { Trash2 } from "lucide-react"
import { Trans, useTranslation } from "react-i18next"
import { SaveButton } from "~/components/Common/SaveButton"
import { deleteWebshare, getAllWebshares, getUserId } from "~/libs/db"
import { deleteWebshare, getAllWebshares, getUserId } from "@/db"
import { getPageShareUrl, setPageShareUrl } from "~/services/ollama"
import { verifyPageShareURL } from "~/utils/verify-page-share"

View File

@@ -5,7 +5,7 @@ import {
formatToMessage,
deleteByHistoryId,
updateHistory
} from "~/libs/db"
} from "@/db"
import { Empty, Skeleton } from "antd"
import { useMessageOption } from "~/hooks/useMessageOption"
import { PencilIcon, Trash2 } from "lucide-react"