feat: add IoD search
This commit is contained in:
@@ -18,7 +18,7 @@ import { useTTS } from "@/hooks/useTTS"
|
||||
import { tagColors } from "@/utils/color"
|
||||
import { removeModelSuffix } from "@/db/models"
|
||||
import { GenerationInfo } from "./GenerationInfo"
|
||||
import { parseReasoning, } from "@/libs/reasoning"
|
||||
import { parseReasoning } from "@/libs/reasoning"
|
||||
import { humanizeMilliseconds } from "@/utils/humanize-milliseconds"
|
||||
type Props = {
|
||||
message: string
|
||||
@@ -36,7 +36,8 @@ type Props = {
|
||||
isProcessing: boolean
|
||||
webSearch?: {}
|
||||
isSearchingInternet?: boolean
|
||||
sources?: any[]
|
||||
webSources?: any[]
|
||||
iodSources?: any[]
|
||||
hideEditAndRegenerate?: boolean
|
||||
onSourceClick?: (source: any) => void
|
||||
isTTSEnabled?: boolean
|
||||
@@ -166,7 +167,7 @@ export const PlaygroundMessage = (props: Props) => {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{props.isBot && props?.sources && props?.sources.length > 0 && (
|
||||
{props.isBot && props?.webSources && props?.webSources.length > 0 && (
|
||||
<Collapse
|
||||
className="mt-6"
|
||||
ghost
|
||||
@@ -175,15 +176,44 @@ export const PlaygroundMessage = (props: Props) => {
|
||||
key: "1",
|
||||
label: (
|
||||
<div className="italic text-gray-500 dark:text-gray-400">
|
||||
{t("citations")}
|
||||
{t("webCitations")}
|
||||
</div>
|
||||
),
|
||||
children: (
|
||||
<div className="mb-3 flex flex-wrap gap-2">
|
||||
{props?.sources?.map((source, index) => (
|
||||
{props?.webSources?.map((source, index) => (
|
||||
<MessageSource
|
||||
onSourceClick={props.onSourceClick}
|
||||
key={index}
|
||||
index={index}
|
||||
source={source}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
]}
|
||||
/>
|
||||
)}
|
||||
{props.isBot && props?.iodSources && props?.iodSources.length > 0 && (
|
||||
<Collapse
|
||||
className="mt-6"
|
||||
ghost
|
||||
items={[
|
||||
{
|
||||
key: "1",
|
||||
label: (
|
||||
<div className="italic text-gray-500 dark:text-gray-400">
|
||||
{t("iodCitations")}
|
||||
</div>
|
||||
),
|
||||
children: (
|
||||
<div className="mb-3 flex flex-wrap gap-2">
|
||||
{props?.iodSources?.map((source, index) => (
|
||||
<MessageSource
|
||||
onSourceClick={props.onSourceClick}
|
||||
key={index}
|
||||
index={index}
|
||||
source={source}
|
||||
/>
|
||||
))}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { useState } from "react"
|
||||
import type React from "react"
|
||||
import { KnowledgeIcon } from "@/components/Option/Knowledge/KnowledgeIcon"
|
||||
|
||||
type Props = {
|
||||
index: number
|
||||
source: {
|
||||
name?: string
|
||||
url?: string
|
||||
@@ -8,11 +11,20 @@ type Props = {
|
||||
type?: string
|
||||
pageContent?: string
|
||||
content?: string
|
||||
doId?: string
|
||||
description?: string
|
||||
}
|
||||
onSourceClick?: (source: any) => void
|
||||
}
|
||||
|
||||
export const MessageSource: React.FC<Props> = ({ source, onSourceClick }) => {
|
||||
export const MessageSource: React.FC<Props> = ({
|
||||
index,
|
||||
source,
|
||||
onSourceClick
|
||||
}) => {
|
||||
// Add state for tracking and content visibility
|
||||
const [showContent, setShowContent] = useState(false)
|
||||
|
||||
if (source?.mode === "rag" || source?.mode === "chat") {
|
||||
return (
|
||||
<button
|
||||
@@ -26,12 +38,46 @@ export const MessageSource: React.FC<Props> = ({ source, onSourceClick }) => {
|
||||
)
|
||||
}
|
||||
|
||||
const onContextMenu = (e: React.MouseEvent) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation
|
||||
setShowContent(true)
|
||||
}
|
||||
|
||||
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>
|
||||
<div className="block items-center gap-1 text-xs text-gray-800 dark:text-gray-100 mb-1">
|
||||
<span className="text-xs font-medium"></span>{" "}
|
||||
<a
|
||||
href={source?.url}
|
||||
target="_blank"
|
||||
onContextMenu={onContextMenu}
|
||||
className="inline-block 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">
|
||||
{source.doId ? (
|
||||
<>
|
||||
<span className="text-xs">
|
||||
[{index + 1}] doid: {source.doId}
|
||||
</span>
|
||||
<br />
|
||||
<span className="text-xs">{source.name}</span>
|
||||
{showContent && (
|
||||
<div className="mt-2 p-2 border-t border-gray-200 dark:border-gray-700">
|
||||
{source.content || source.pageContent || source.description}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<span className="text-xs">
|
||||
[{index + 1}] {source.name}
|
||||
</span>
|
||||
{showContent && (
|
||||
<div className="mt-2 p-2 border-t border-gray-200 dark:border-gray-700">
|
||||
{source.content || source.pageContent}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</a>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user