knownledge preview
This commit is contained in:
parent
0de5ea0b04
commit
d6d2eae5ef
@ -27,6 +27,10 @@ const formatChatHistoryAsString = (history: BaseMessage[]) => {
|
||||
|
||||
export const formatDocs = (docs: Document[]) => {
|
||||
return docs
|
||||
.filter(
|
||||
(doc, i, self) =>
|
||||
self.findIndex((d) => d.pageContent === doc.pageContent) === i
|
||||
)
|
||||
.map((doc, i) => `<doc id='${i}'>${doc.pageContent}</doc>`)
|
||||
.join("\n")
|
||||
}
|
||||
@ -145,7 +149,7 @@ export const createChatWithXChain = ({
|
||||
runName: "Itemgetter:question"
|
||||
}),
|
||||
chat_history: RunnableLambda.from(serializeHistory).withConfig({
|
||||
runName: "SerializeHistory",
|
||||
runName: "SerializeHistory"
|
||||
})
|
||||
},
|
||||
context,
|
||||
|
@ -5,6 +5,7 @@ import { WebSearch } from "./WebSearch"
|
||||
import { CheckIcon, ClipboardIcon, Pen, RotateCcw } from "lucide-react"
|
||||
import { EditMessageForm } from "./EditMessageForm"
|
||||
import { useTranslation } from "react-i18next"
|
||||
import { MessageSource } from "./MessageSource"
|
||||
|
||||
type Props = {
|
||||
message: string
|
||||
@ -23,6 +24,7 @@ type Props = {
|
||||
isSearchingInternet?: boolean
|
||||
sources?: any[]
|
||||
hideEditAndRegenerate?: boolean
|
||||
onSourceClick?: (source: any) => void
|
||||
}
|
||||
|
||||
export const PlaygroundMessage = (props: Props) => {
|
||||
@ -95,13 +97,9 @@ export const PlaygroundMessage = (props: Props) => {
|
||||
{props.isBot && props?.sources && props?.sources.length > 0 && (
|
||||
<div className="mb-3 flex flex-wrap gap-2">
|
||||
{props?.sources?.map((source, index) => (
|
||||
<a
|
||||
key={index}
|
||||
href={source?.url}
|
||||
target="_blank"
|
||||
className="inline-flex cursor-pointer transition-shadow duration-300 ease-in-out hover:shadow-lg items-center rounded-md bg-gray-100 p-1 text-xs text-gray-800 border border-gray-300 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-100 opacity-80 hover:opacity-100">
|
||||
<span className="text-xs">{source.name}</span>
|
||||
</a>
|
||||
<MessageSource
|
||||
onSourceClick={props.onSourceClick}
|
||||
key={index} source={source} />
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
37
src/components/Common/Playground/MessageSource.tsx
Normal file
37
src/components/Common/Playground/MessageSource.tsx
Normal file
@ -0,0 +1,37 @@
|
||||
import { KnowledgeIcon } from "@/components/Option/Knowledge/KnowledgeIcon"
|
||||
|
||||
type Props = {
|
||||
source: {
|
||||
name?: string
|
||||
url?: string
|
||||
mode?: string
|
||||
type?: string
|
||||
pageContent?: string
|
||||
content?: string
|
||||
}
|
||||
onSourceClick?: (source: any) => void
|
||||
}
|
||||
|
||||
export const MessageSource: React.FC<Props> = ({ source, onSourceClick }) => {
|
||||
if (source?.mode === "rag") {
|
||||
return (
|
||||
<button
|
||||
onClick={() => {
|
||||
onSourceClick && onSourceClick(source)
|
||||
}}
|
||||
className="inline-flex gap-2 cursor-pointer transition-shadow duration-300 ease-in-out hover:shadow-lg items-center rounded-md bg-gray-100 p-1 text-xs text-gray-800 border border-gray-300 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-100 opacity-80 hover:opacity-100">
|
||||
<KnowledgeIcon type={source.type} className="h-4 w-5" />
|
||||
<span className="text-xs">{source.name}</span>
|
||||
</button>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<a
|
||||
href={source?.url}
|
||||
target="_blank"
|
||||
className="inline-flex cursor-pointer transition-shadow duration-300 ease-in-out hover:shadow-lg items-center rounded-md bg-gray-100 p-1 text-xs text-gray-800 border border-gray-300 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-100 opacity-80 hover:opacity-100">
|
||||
<span className="text-xs">{source.name}</span>
|
||||
</a>
|
||||
)
|
||||
}
|
52
src/components/Common/Playground/MessageSourcePopup.tsx
Normal file
52
src/components/Common/Playground/MessageSourcePopup.tsx
Normal file
@ -0,0 +1,52 @@
|
||||
import { KnowledgeIcon } from "@/components/Option/Knowledge/KnowledgeIcon"
|
||||
import { Modal } from "antd"
|
||||
|
||||
type Props = {
|
||||
source: any
|
||||
open: boolean
|
||||
setOpen: (open: boolean) => void
|
||||
}
|
||||
|
||||
export const MessageSourcePopup: React.FC<Props> = ({
|
||||
source,
|
||||
open,
|
||||
setOpen
|
||||
}) => {
|
||||
return (
|
||||
<Modal
|
||||
open={open}
|
||||
// mask={false}
|
||||
zIndex={10000}
|
||||
onCancel={() => setOpen(false)}
|
||||
footer={null}
|
||||
onOk={() => setOpen(false)}>
|
||||
<div className="flex flex-col gap-2 mt-6">
|
||||
<h4 className="bg-gray-100 text-md dark:bg-gray-800 inline-flex gap-2 items-center text-gray-800 dark:text-gray-100 font-semibold p-2">
|
||||
{source?.type && (
|
||||
<KnowledgeIcon type={source?.type} className="h-4 w-5" />
|
||||
)}
|
||||
{source?.name}
|
||||
</h4>
|
||||
{source?.type === "pdf" ? (
|
||||
<>
|
||||
<p className="text-gray-500 text-sm">{source?.pageContent}</p>
|
||||
|
||||
<div className="flex flex-wrap gap-3">
|
||||
<span className="border border-gray-300 dark:border-gray-700 rounded-md p-1 text-gray-500 text-xs">
|
||||
{`Page ${source?.metadata?.page}`}
|
||||
</span>
|
||||
|
||||
<span className="border border-gray-300 dark:border-gray-700 rounded-md p-1 text-xs text-gray-500">
|
||||
{`Line ${source?.metadata?.loc?.lines?.from} - ${source?.metadata?.loc?.lines?.to}`}
|
||||
</span>
|
||||
</div>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<p className="text-gray-500 text-sm">{source?.pageContent}</p>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</Modal>
|
||||
)
|
||||
}
|
@ -2,6 +2,7 @@ import React from "react"
|
||||
import { useMessageOption } from "~/hooks/useMessageOption"
|
||||
import { PlaygroundEmpty } from "./PlaygroundEmpty"
|
||||
import { PlaygroundMessage } from "~/components/Common/Playground/Message"
|
||||
import { MessageSourcePopup } from "@/components/Common/Playground/MessageSourcePopup"
|
||||
|
||||
export const PlaygroundChat = () => {
|
||||
const {
|
||||
@ -12,41 +13,55 @@ export const PlaygroundChat = () => {
|
||||
editMessage
|
||||
} = useMessageOption()
|
||||
const divRef = React.useRef<HTMLDivElement>(null)
|
||||
const [isSourceOpen, setIsSourceOpen] = React.useState(false)
|
||||
const [source, setSource] = React.useState<any>(null)
|
||||
React.useEffect(() => {
|
||||
if (divRef.current) {
|
||||
divRef.current.scrollIntoView({ behavior: "smooth" })
|
||||
}
|
||||
})
|
||||
return (
|
||||
<div className="grow flex flex-col md:translate-x-0 transition-transform duration-300 ease-in-out">
|
||||
{messages.length === 0 && (
|
||||
<div className="mt-32">
|
||||
<PlaygroundEmpty />
|
||||
</div>
|
||||
)}
|
||||
{/* {messages.length > 0 && <div className="w-full h-16 flex-shrink-0"></div>} */}
|
||||
{messages.map((message, index) => (
|
||||
<PlaygroundMessage
|
||||
key={index}
|
||||
isBot={message.isBot}
|
||||
message={message.message}
|
||||
name={message.name}
|
||||
images={message.images || []}
|
||||
currentMessageIndex={index}
|
||||
totalMessages={messages.length}
|
||||
onRengerate={regenerateLastMessage}
|
||||
isProcessing={streaming}
|
||||
isSearchingInternet={isSearchingInternet}
|
||||
sources={message.sources}
|
||||
onEditFormSubmit={(value) => {
|
||||
editMessage(index, value, !message.isBot)
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
{messages.length > 0 && (
|
||||
<div className="w-full h-32 md:h-48 flex-shrink-0"></div>
|
||||
)}
|
||||
<div ref={divRef} />
|
||||
</div>
|
||||
<>
|
||||
{" "}
|
||||
<div className="grow flex flex-col md:translate-x-0 transition-transform duration-300 ease-in-out">
|
||||
{messages.length === 0 && (
|
||||
<div className="mt-32">
|
||||
<PlaygroundEmpty />
|
||||
</div>
|
||||
)}
|
||||
{/* {messages.length > 0 && <div className="w-full h-16 flex-shrink-0"></div>} */}
|
||||
{messages.map((message, index) => (
|
||||
<PlaygroundMessage
|
||||
key={index}
|
||||
isBot={message.isBot}
|
||||
message={message.message}
|
||||
name={message.name}
|
||||
images={message.images || []}
|
||||
currentMessageIndex={index}
|
||||
totalMessages={messages.length}
|
||||
onRengerate={regenerateLastMessage}
|
||||
isProcessing={streaming}
|
||||
isSearchingInternet={isSearchingInternet}
|
||||
sources={message.sources}
|
||||
onEditFormSubmit={(value) => {
|
||||
editMessage(index, value, !message.isBot)
|
||||
}}
|
||||
onSourceClick={(data) => {
|
||||
setSource(data)
|
||||
setIsSourceOpen(true)
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
{messages.length > 0 && (
|
||||
<div className="w-full h-32 md:h-48 flex-shrink-0"></div>
|
||||
)}
|
||||
<div ref={divRef} />
|
||||
</div>
|
||||
<MessageSourcePopup
|
||||
open={isSourceOpen}
|
||||
setOpen={setIsSourceOpen}
|
||||
source={source}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
@ -28,7 +28,6 @@ export class PageAssistVectorDb {
|
||||
} else {
|
||||
const data = result[id] as VectorData
|
||||
if (!data) {
|
||||
console.log("Creating new vector", vector)
|
||||
this.db.set({ [id]: { id, vectors: vector } }, () => {
|
||||
if (chrome.runtime.lastError) {
|
||||
reject(chrome.runtime.lastError)
|
||||
@ -37,7 +36,6 @@ export class PageAssistVectorDb {
|
||||
}
|
||||
})
|
||||
} else {
|
||||
console.log("Concatenating vectors")
|
||||
this.db.set(
|
||||
{
|
||||
[id]: {
|
||||
|
@ -601,8 +601,10 @@ export const useMessageOption = () => {
|
||||
const context = formatDocs(docs)
|
||||
const source = docs.map((doc) => {
|
||||
return {
|
||||
...doc,
|
||||
name: doc?.metadata?.source || "untitled",
|
||||
type: doc?.metadata?.type || "unknown",
|
||||
mode: "rag",
|
||||
url: ""
|
||||
}
|
||||
})
|
||||
|
@ -136,7 +136,6 @@ export class PageAssistVectorStore extends VectorStore {
|
||||
}),
|
||||
search.similarity
|
||||
])
|
||||
console.log(result)
|
||||
return result
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ export class PageAssisTXTUrlLoader
|
||||
const raw = await res.text()
|
||||
|
||||
const parsed = await this.parse(raw)
|
||||
let metadata = { source: this.name, type: "csv" }
|
||||
let metadata = { source: this.name, type: "txt" }
|
||||
parsed.forEach((pageContent, i) => {
|
||||
if (typeof pageContent !== "string") {
|
||||
throw new Error(
|
||||
|
Loading…
x
Reference in New Issue
Block a user