Unverified Commit 23e34136 authored by Joel's avatar Joel Committed by GitHub

feat: chat in explore support agent (#647)

Co-authored-by: 's avatarStyleZhang <jasonapring2015@outlook.com>
parent 4fdb3777
import type { FC } from 'react'
import React from 'react'
import UniversalChat from '@/app/components/explore/universal-chat'
const Chat: FC = () => {
return (
<div className='h-full p-2'>
<UniversalChat />
</div>
)
}
export default React.memo(Chat)
...@@ -5,6 +5,8 @@ import { AppContextProvider } from '@/context/app-context' ...@@ -5,6 +5,8 @@ import { AppContextProvider } from '@/context/app-context'
import GA, { GaType } from '@/app/components/base/ga' import GA, { GaType } from '@/app/components/base/ga'
import HeaderWrapper from '@/app/components/header/HeaderWrapper' import HeaderWrapper from '@/app/components/header/HeaderWrapper'
import Header from '@/app/components/header' import Header from '@/app/components/header'
import { EventEmitterContextProvider } from '@/context/event-emitter'
import { ProviderContextProvider } from '@/context/provider-context'
const Layout = ({ children }: { children: ReactNode }) => { const Layout = ({ children }: { children: ReactNode }) => {
return ( return (
...@@ -12,10 +14,14 @@ const Layout = ({ children }: { children: ReactNode }) => { ...@@ -12,10 +14,14 @@ const Layout = ({ children }: { children: ReactNode }) => {
<GA gaType={GaType.admin} /> <GA gaType={GaType.admin} />
<SwrInitor> <SwrInitor>
<AppContextProvider> <AppContextProvider>
<HeaderWrapper> <EventEmitterContextProvider>
<Header /> <ProviderContextProvider>
</HeaderWrapper> <HeaderWrapper>
{children} <Header />
</HeaderWrapper>
{children}
</ProviderContextProvider>
</EventEmitterContextProvider>
</AppContextProvider> </AppContextProvider>
</SwrInitor> </SwrInitor>
</> </>
......
This diff is collapsed.
import type { FC } from 'react'
import { HandThumbDownIcon, HandThumbUpIcon } from '@heroicons/react/24/outline'
export const stopIcon = (
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fillRule="evenodd" clipRule="evenodd" d="M7.00004 0.583313C3.45621 0.583313 0.583374 3.45615 0.583374 6.99998C0.583374 10.5438 3.45621 13.4166 7.00004 13.4166C10.5439 13.4166 13.4167 10.5438 13.4167 6.99998C13.4167 3.45615 10.5439 0.583313 7.00004 0.583313ZM4.73029 4.98515C4.66671 5.10993 4.66671 5.27328 4.66671 5.59998V8.39998C4.66671 8.72668 4.66671 8.89003 4.73029 9.01481C4.78621 9.12457 4.87545 9.21381 4.98521 9.26973C5.10999 9.33331 5.27334 9.33331 5.60004 9.33331H8.40004C8.72674 9.33331 8.89009 9.33331 9.01487 9.26973C9.12463 9.21381 9.21387 9.12457 9.2698 9.01481C9.33337 8.89003 9.33337 8.72668 9.33337 8.39998V5.59998C9.33337 5.27328 9.33337 5.10993 9.2698 4.98515C9.21387 4.87539 9.12463 4.78615 9.01487 4.73023C8.89009 4.66665 8.72674 4.66665 8.40004 4.66665H5.60004C5.27334 4.66665 5.10999 4.66665 4.98521 4.73023C4.87545 4.78615 4.78621 4.87539 4.73029 4.98515Z" fill="#667085" />
</svg>
)
export const OpeningStatementIcon: FC<{ className?: string }> = ({ className }) => (
<svg className={className} width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fillRule="evenodd" clipRule="evenodd" d="M6.25002 1C3.62667 1 1.50002 3.12665 1.50002 5.75C1.50002 6.28 1.58702 6.79071 1.7479 7.26801C1.7762 7.35196 1.79285 7.40164 1.80368 7.43828L1.80722 7.45061L1.80535 7.45452C1.79249 7.48102 1.77339 7.51661 1.73766 7.58274L0.911727 9.11152C0.860537 9.20622 0.807123 9.30503 0.770392 9.39095C0.733879 9.47635 0.674738 9.63304 0.703838 9.81878C0.737949 10.0365 0.866092 10.2282 1.05423 10.343C1.21474 10.4409 1.38213 10.4461 1.475 10.4451C1.56844 10.444 1.68015 10.4324 1.78723 10.4213L4.36472 10.1549C4.406 10.1506 4.42758 10.1484 4.44339 10.1472L4.44542 10.147L4.45161 10.1492C4.47103 10.1562 4.49738 10.1663 4.54285 10.1838C5.07332 10.3882 5.64921 10.5 6.25002 10.5C8.87338 10.5 11 8.37335 11 5.75C11 3.12665 8.87338 1 6.25002 1ZM4.48481 4.29111C5.04844 3.81548 5.7986 3.9552 6.24846 4.47463C6.69831 3.9552 7.43879 3.82048 8.01211 4.29111C8.58544 4.76175 8.6551 5.562 8.21247 6.12453C7.93825 6.47305 7.24997 7.10957 6.76594 7.54348C6.58814 7.70286 6.49924 7.78255 6.39255 7.81466C6.30103 7.84221 6.19589 7.84221 6.10436 7.81466C5.99767 7.78255 5.90878 7.70286 5.73098 7.54348C5.24694 7.10957 4.55867 6.47305 4.28444 6.12453C3.84182 5.562 3.92117 4.76675 4.48481 4.29111Z" fill="#667085" />
</svg>
)
export const RatingIcon: FC<{ isLike: boolean }> = ({ isLike }) => {
return isLike ? <HandThumbUpIcon className='w-4 h-4' /> : <HandThumbDownIcon className='w-4 h-4' />
}
export const EditIcon: FC<{ className?: string }> = ({ className }) => {
return <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" className={className}>
<path d="M14 11.9998L13.3332 12.7292C12.9796 13.1159 12.5001 13.3332 12.0001 13.3332C11.5001 13.3332 11.0205 13.1159 10.6669 12.7292C10.3128 12.3432 9.83332 12.1265 9.33345 12.1265C8.83359 12.1265 8.35409 12.3432 7.99998 12.7292M2 13.3332H3.11636C3.44248 13.3332 3.60554 13.3332 3.75899 13.2963C3.89504 13.2637 4.0251 13.2098 4.1444 13.1367C4.27895 13.0542 4.39425 12.9389 4.62486 12.7083L13 4.33316C13.5523 3.78087 13.5523 2.88544 13 2.33316C12.4477 1.78087 11.5523 1.78087 11 2.33316L2.62484 10.7083C2.39424 10.9389 2.27894 11.0542 2.19648 11.1888C2.12338 11.3081 2.0695 11.4381 2.03684 11.5742C2 11.7276 2 11.8907 2 12.2168V13.3332Z" stroke="#6B7280" strokeLinecap="round" strokeLinejoin="round" />
</svg>
}
export const EditIconSolid: FC<{ className?: string }> = ({ className }) => {
return <svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg" className={className}>
<path fillRule="evenodd" clipRule="evenodd" d="M10.8374 8.63108C11.0412 8.81739 11.0554 9.13366 10.8691 9.33747L10.369 9.88449C10.0142 10.2725 9.52293 10.5001 9.00011 10.5001C8.47746 10.5001 7.98634 10.2727 7.63157 9.8849C7.45561 9.69325 7.22747 9.59515 7.00014 9.59515C6.77271 9.59515 6.54446 9.69335 6.36846 9.88517C6.18177 10.0886 5.86548 10.1023 5.66201 9.91556C5.45853 9.72888 5.44493 9.41259 5.63161 9.20911C5.98678 8.82201 6.47777 8.59515 7.00014 8.59515C7.52251 8.59515 8.0135 8.82201 8.36867 9.20911L8.36924 9.20974C8.54486 9.4018 8.77291 9.50012 9.00011 9.50012C9.2273 9.50012 9.45533 9.40182 9.63095 9.20979L10.131 8.66276C10.3173 8.45895 10.6336 8.44476 10.8374 8.63108Z" fill="#6B7280" />
<path fillRule="evenodd" clipRule="evenodd" d="M7.89651 1.39656C8.50599 0.787085 9.49414 0.787084 10.1036 1.39656C10.7131 2.00604 10.7131 2.99419 10.1036 3.60367L3.82225 9.88504C3.81235 9.89494 3.80254 9.90476 3.79281 9.91451C3.64909 10.0585 3.52237 10.1855 3.3696 10.2791C3.23539 10.3613 3.08907 10.4219 2.93602 10.4587C2.7618 10.5005 2.58242 10.5003 2.37897 10.5001C2.3652 10.5001 2.35132 10.5001 2.33732 10.5001H1.50005C1.22391 10.5001 1.00005 10.2763 1.00005 10.0001V9.16286C1.00005 9.14886 1.00004 9.13497 1.00003 9.1212C0.999836 8.91776 0.999669 8.73838 1.0415 8.56416C1.07824 8.4111 1.13885 8.26479 1.22109 8.13058C1.31471 7.97781 1.44166 7.85109 1.58566 7.70736C1.5954 7.69764 1.60523 7.68783 1.61513 7.67793L7.89651 1.39656Z" fill="#6B7280" />
</svg>
}
export const TryToAskIcon = (
<svg width="11" height="10" viewBox="0 0 11 10" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5.88889 0.683718C5.827 0.522805 5.67241 0.416626 5.5 0.416626C5.3276 0.416626 5.173 0.522805 5.11111 0.683718L4.27279 2.86334C4.14762 3.18877 4.10829 3.28255 4.05449 3.35821C4.00051 3.43413 3.93418 3.50047 3.85826 3.55445C3.78259 3.60825 3.68881 3.64758 3.36338 3.77275L1.18376 4.61106C1.02285 4.67295 0.916668 4.82755 0.916668 4.99996C0.916668 5.17236 1.02285 5.32696 1.18376 5.38885L3.36338 6.22717C3.68881 6.35234 3.78259 6.39167 3.85826 6.44547C3.93418 6.49945 4.00051 6.56578 4.05449 6.6417C4.10829 6.71737 4.14762 6.81115 4.27279 7.13658L5.11111 9.3162C5.173 9.47711 5.3276 9.58329 5.5 9.58329C5.67241 9.58329 5.82701 9.47711 5.8889 9.3162L6.72721 7.13658C6.85238 6.81115 6.89171 6.71737 6.94551 6.6417C6.99949 6.56578 7.06583 6.49945 7.14175 6.44547C7.21741 6.39167 7.31119 6.35234 7.63662 6.22717L9.81624 5.38885C9.97715 5.32696 10.0833 5.17236 10.0833 4.99996C10.0833 4.82755 9.97715 4.67295 9.81624 4.61106L7.63662 3.77275C7.31119 3.64758 7.21741 3.60825 7.14175 3.55445C7.06583 3.50047 6.99949 3.43413 6.94551 3.35821C6.89171 3.28255 6.85238 3.18877 6.72721 2.86334L5.88889 0.683718Z" fill="#667085" />
</svg>
)
This diff is collapsed.
'use client'
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import type { MessageMore } from '../type'
import { formatNumber } from '@/utils/format'
export type IMoreInfoProps = { more: MessageMore; isQuestion: boolean }
const MoreInfo: FC<IMoreInfoProps> = ({ more, isQuestion }) => {
const { t } = useTranslation()
return (<div className={`mt-1 space-x-2 text-xs text-gray-400 ${isQuestion ? 'mr-2 text-right ' : 'ml-2 text-left float-right'}`}>
<span>{`${t('appLog.detail.timeConsuming')} ${more.latency}${t('appLog.detail.second')}`}</span>
<span>{`${t('appLog.detail.tokenCost')} ${formatNumber(more.tokens)}`}</span>
<span>· </span>
<span>{more.time} </span>
</div>)
}
export default React.memo(MoreInfo)
'use client'
import React from 'react'
const OperationBtn = ({ innerContent, onClick, className }: { innerContent: React.ReactNode; onClick?: () => void; className?: string }) => (
<div
className={`relative box-border flex items-center justify-center h-7 w-7 p-0.5 rounded-lg bg-white cursor-pointer text-gray-500 hover:text-gray-800 ${className ?? ''}`}
style={{ boxShadow: '0px 4px 6px -1px rgba(0, 0, 0, 0.1), 0px 2px 4px -2px rgba(0, 0, 0, 0.05)' }}
onClick={onClick && onClick}
>
{innerContent}
</div>
)
export default OperationBtn
'use client'
import type { FC } from 'react'
import React from 'react'
import { useContext } from 'use-context-selector'
import s from '../style.module.css'
import type { IChatItem } from '../type'
import MoreInfo from '../more-info'
import AppContext from '@/context/app-context'
import { Markdown } from '@/app/components/base/markdown'
type IQuestionProps = Pick<IChatItem, 'id' | 'content' | 'more' | 'useCurrentUserAvatar'>
const Question: FC<IQuestionProps> = ({ id, content, more, useCurrentUserAvatar }) => {
const { userProfile } = useContext(AppContext)
const userName = userProfile?.name
return (
<div className='flex items-start justify-end' key={id}>
<div className={s.questionWrapWrap}>
<div className={`${s.question} relative text-sm text-gray-900`}>
<div
className={'mr-2 py-3 px-4 bg-blue-500 rounded-tl-2xl rounded-b-2xl'}
>
<Markdown content={content} />
</div>
</div>
{more && <MoreInfo more={more} isQuestion={true} />}
</div>
{useCurrentUserAvatar
? (
<div className='w-10 h-10 shrink-0 leading-10 text-center mr-2 rounded-full bg-primary-600 text-white'>
{userName?.[0].toLocaleUpperCase()}
</div>
)
: (
<div className={`${s.questionIcon} w-10 h-10 shrink-0 `}></div>
)}
</div>
)
}
export default React.memo(Question)
'use client'
import type { FC } from 'react'
import React from 'react'
import cn from 'classnames'
import { useTranslation } from 'react-i18next'
import type { ThoughtItem } from '../type'
import s from './style.module.css'
import { DataSet as DataSetIcon, Loading as LodingIcon, Search, ThoughtList, WebReader } from '@/app/components/base/icons/src/public/thought'
import { ChevronDown } from '@/app/components/base/icons/src/vender/line/arrows'
import type { DataSet } from '@/models/datasets'
export type IThoughtProps = {
list: ThoughtItem[]
isThinking?: boolean
dataSets?: DataSet[]
}
const getIcon = (toolId: string) => {
switch (toolId) {
case 'dataset':
return <DataSetIcon />
case 'web_reader':
return <WebReader />
default:
return <Search />
}
}
const Thought: FC<IThoughtProps> = ({
list,
isThinking,
dataSets,
}) => {
const { t } = useTranslation()
const [isShowDetail, setIsShowDetail] = React.useState(false)
const getThoughtText = (item: ThoughtItem) => {
try {
const input = JSON.parse(item.tool_input)
switch (item.tool) {
case 'dataset':
// eslint-disable-next-line no-case-declarations
const datasetName = dataSets?.find(item => item.id === input.dataset_id)?.name || 'unknown dataset'
return t('explore.universalChat.thought.res.dataset').replace('{datasetName}', `<span class="text-gray-700">${datasetName}</span>`)
case 'web_reader':
return t(`explore.universalChat.thought.res.webReader.${!input.cursor ? 'normal' : 'hasPageInfo'}`).replace('{url}', `<a href="${input.url}" class="text-[#155EEF]">${input.url}</a>`)
default: // google, wikipedia
return t('explore.universalChat.thought.res.search', { query: input.query })
}
}
catch (error) {
console.error(error)
return item
}
}
const renderItem = (item: ThoughtItem) => (
<div className='flex space-x-1 py-[3px] leading-[18px]' key={item.id}>
<div className='flex items-center h-[18px] shrink-0'>{getIcon(item.tool)}</div>
<div dangerouslySetInnerHTML={{
__html: getThoughtText(item),
// item.thought.replace(urlRegex, (url) => {
// return `<a href="${url}" class="text-[#155EEF]">${url}</a>`
// }),
}}></div>
</div>
)
return (
<div className={cn(s.wrap, !isShowDetail && s.wrapHoverEffect, 'inline-block mb-2 px-2 py-0.5 rounded-md text-xs text-gray-500 font-medium')} >
<div className='flex items-center h-6 space-x-1 cursor-pointer' onClick={() => setIsShowDetail(!isShowDetail)} >
{!isThinking ? <ThoughtList /> : <div className='animate-spin'><LodingIcon /></div>}
<div dangerouslySetInnerHTML= {{
__html: isThinking ? getThoughtText(list[list.length - 1]) : (t(`explore.universalChat.thought.${isShowDetail ? 'hide' : 'show'}`) + t('explore.universalChat.thought.processOfThought')),
}}
></div>
<ChevronDown className={isShowDetail ? 'rotate-180' : '' } />
</div>
{isShowDetail && (
<div>
{list.map(item => renderItem(item))}
</div>
)}
</div>
)
}
export default React.memo(Thought)
.wrap {
background-color: rgba(255, 255, 255, 0.92);
}
.wrapHoverEffect:hover{
box-shadow: 0px 1px 2px 0px rgba(16, 24, 40, 0.06), 0px 1px 3px 0px rgba(16, 24, 40, 0.1);
}
\ No newline at end of file
import type { Annotation, MessageRating } from '@/models/log'
export type MessageMore = {
time: string
tokens: number
latency: number | string
}
export type Feedbacktype = {
rating: MessageRating
content?: string | null
}
export type FeedbackFunc = (messageId: string, feedback: Feedbacktype) => Promise<any>
export type SubmitAnnotationFunc = (messageId: string, content: string) => Promise<any>
export type DisplayScene = 'web' | 'console'
export type ThoughtItem = {
id: string
tool: string // plugin or dataset
thought: string
tool_input: string
message_id: string
}
export type IChatItem = {
id: string
content: string
agent_thoughts?: ThoughtItem[]
/**
* Specific message type
*/
isAnswer: boolean
/**
* The user feedback result of this message
*/
feedback?: Feedbacktype
/**
* The admin feedback result of this message
*/
adminFeedback?: Feedbacktype
/**
* Whether to hide the feedback area
*/
feedbackDisabled?: boolean
/**
* More information about this message
*/
more?: MessageMore
annotation?: Annotation
useCurrentUserAvatar?: boolean
isOpeningStatement?: boolean
}
'use client' 'use client'
import React, { FC, ReactNode } from 'react' import type { FC, ReactNode } from 'react'
import React from 'react'
import cn from 'classnames' import cn from 'classnames'
export interface IFeaturePanelProps { export type IFeaturePanelProps = {
className?: string className?: string
headerIcon: ReactNode headerIcon?: ReactNode
title: ReactNode title: ReactNode
headerRight: ReactNode headerRight?: ReactNode
hasHeaderBottomBorder?: boolean hasHeaderBottomBorder?: boolean
isFocus?: boolean isFocus?: boolean
noBodySpacing?: boolean noBodySpacing?: boolean
...@@ -26,15 +27,17 @@ const FeaturePanel: FC<IFeaturePanelProps> = ({ ...@@ -26,15 +27,17 @@ const FeaturePanel: FC<IFeaturePanelProps> = ({
return ( return (
<div <div
className={cn(className, isFocus && 'border border-[#2D0DEE]', 'rounded-xl bg-gray-50 pt-2 pb-3', noBodySpacing && '!pb-0')} className={cn(className, isFocus && 'border border-[#2D0DEE]', 'rounded-xl bg-gray-50 pt-2 pb-3', noBodySpacing && '!pb-0')}
style={isFocus ? { style={isFocus
boxShadow: '0px 4px 8px -2px rgba(16, 24, 40, 0.1), 0px 2px 4px -2px rgba(16, 24, 40, 0.06)', ? {
} : {}} boxShadow: '0px 4px 8px -2px rgba(16, 24, 40, 0.1), 0px 2px 4px -2px rgba(16, 24, 40, 0.06)',
}
: {}}
> >
{/* Header */} {/* Header */}
<div className={cn('pb-2 px-3', hasHeaderBottomBorder && 'border-b border-gray-100')}> <div className={cn('pb-2 px-3', hasHeaderBottomBorder && 'border-b border-gray-100')}>
<div className='flex justify-between items-center h-8'> <div className='flex justify-between items-center h-8'>
<div className='flex items-center space-x-1 shrink-0'> <div className='flex items-center space-x-1 shrink-0'>
<div className='flex items-center justify-center w-4 h-4'>{headerIcon}</div> {headerIcon && <div className='flex items-center justify-center w-4 h-4'>{headerIcon}</div>}
<div className='text-sm font-semibold text-gray-800'>{title}</div> <div className='text-sm font-semibold text-gray-800'>{title}</div>
</div> </div>
<div> <div>
......
'use client'
import type { FC } from 'react'
import React from 'react'
import { ProviderType } from '@/types/app'
import { MODEL_LIST } from '@/config'
import { Anthropic, Gpt3, Gpt4 } from '@/app/components/base/icons/src/public/llm'
export type IModelIconProps = { modelId: string; className?: string }
const ModelIcon: FC<IModelIconProps> = ({ modelId, className }) => {
const resClassName = `w-4 h-4 ${className}`
const model = MODEL_LIST.find(item => item.id === modelId)
if (model?.id === 'gpt-4')
return <Gpt4 className={resClassName} />
if (model?.provider === ProviderType.anthropic) {
return (
<Anthropic className={resClassName} />
)
}
return (
<Gpt3 className={resClassName} />
)
}
export default React.memo(ModelIcon)
...@@ -4,7 +4,6 @@ import React from 'react' ...@@ -4,7 +4,6 @@ import React from 'react'
import { useContext } from 'use-context-selector' import { useContext } from 'use-context-selector'
import produce from 'immer' import produce from 'immer'
import { useBoolean } from 'ahooks' import { useBoolean } from 'ahooks'
import useSWR from 'swr'
import DatasetConfig from '../dataset-config' import DatasetConfig from '../dataset-config'
import ChatGroup from '../features/chat-group' import ChatGroup from '../features/chat-group'
import ExperienceEnchanceGroup from '../features/experience-enchance-group' import ExperienceEnchanceGroup from '../features/experience-enchance-group'
...@@ -20,7 +19,7 @@ import ConfigPrompt from '@/app/components/app/configuration/config-prompt' ...@@ -20,7 +19,7 @@ import ConfigPrompt from '@/app/components/app/configuration/config-prompt'
import ConfigVar from '@/app/components/app/configuration/config-var' import ConfigVar from '@/app/components/app/configuration/config-var'
import type { PromptVariable } from '@/models/debug' import type { PromptVariable } from '@/models/debug'
import { AppType } from '@/types/app' import { AppType } from '@/types/app'
import { fetchTenantInfo } from '@/service/common' import { useProviderContext } from '@/context/provider-context'
const Config: FC = () => { const Config: FC = () => {
const { const {
...@@ -39,8 +38,7 @@ const Config: FC = () => { ...@@ -39,8 +38,7 @@ const Config: FC = () => {
setSpeechToTextConfig, setSpeechToTextConfig,
} = useContext(ConfigContext) } = useContext(ConfigContext)
const isChatApp = mode === AppType.chat const isChatApp = mode === AppType.chat
const { data: userInfo } = useSWR({ url: '/info' }, fetchTenantInfo) const { currentProvider } = useProviderContext()
const openaiProvider = userInfo?.providers?.find(({ token_is_set, is_valid, provider_name }) => token_is_set && is_valid && provider_name === 'openai')
const promptTemplate = modelConfig.configs.prompt_template const promptTemplate = modelConfig.configs.prompt_template
const promptVariables = modelConfig.configs.prompt_variables const promptVariables = modelConfig.configs.prompt_variables
...@@ -92,7 +90,7 @@ const Config: FC = () => { ...@@ -92,7 +90,7 @@ const Config: FC = () => {
}, },
}) })
const hasChatConfig = isChatApp && (featureConfig.openingStatement || featureConfig.suggestedQuestionsAfterAnswer || (featureConfig.speechToText && openaiProvider)) const hasChatConfig = isChatApp && (featureConfig.openingStatement || featureConfig.suggestedQuestionsAfterAnswer || (featureConfig.speechToText && currentProvider?.provider_name === 'openai'))
const hasToolbox = false const hasToolbox = false
const [showAutomatic, { setTrue: showAutomaticTrue, setFalse: showAutomaticFalse }] = useBoolean(false) const [showAutomatic, { setTrue: showAutomaticTrue, setFalse: showAutomaticFalse }] = useBoolean(false)
...@@ -122,7 +120,7 @@ const Config: FC = () => { ...@@ -122,7 +120,7 @@ const Config: FC = () => {
isChatApp={isChatApp} isChatApp={isChatApp}
config={featureConfig} config={featureConfig}
onChange={handleFeatureChange} onChange={handleFeatureChange}
showSpeechToTextItem={!!openaiProvider} showSpeechToTextItem={currentProvider?.provider_name === 'openai'}
/> />
)} )}
{showAutomatic && ( {showAutomatic && (
...@@ -162,7 +160,7 @@ const Config: FC = () => { ...@@ -162,7 +160,7 @@ const Config: FC = () => {
} }
} }
isShowSuggestedQuestionsAfterAnswer={featureConfig.suggestedQuestionsAfterAnswer} isShowSuggestedQuestionsAfterAnswer={featureConfig.suggestedQuestionsAfterAnswer}
isShowSpeechText={featureConfig.speechToText} isShowSpeechText={featureConfig.speechToText && currentProvider?.provider_name === 'openai'}
/> />
) )
} }
......
'use client' 'use client'
import React, { FC } from 'react' import type { FC } from 'react'
import React from 'react'
import cn from 'classnames' import cn from 'classnames'
import TypeIcon from '../type-icon'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { formatNumber } from '@/utils/format' import TypeIcon from '../type-icon'
import RemoveIcon from '../../base/icons/remove-icon' import RemoveIcon from '../../base/icons/remove-icon'
import s from './style.module.css' import s from './style.module.css'
import { formatNumber } from '@/utils/format'
export interface ICardItemProps { export type ICardItemProps = {
className?: string className?: string
config: any config: any
onRemove: (id: string) => void onRemove: (id: string) => void
readonly?: boolean
} }
// const RemoveIcon = ({ className, onClick }: { className: string, onClick: () => void }) => ( // const RemoveIcon = ({ className, onClick }: { className: string, onClick: () => void }) => (
// <svg className={className} onClick={onClick} width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> // <svg className={className} onClick={onClick} width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
// <path d="M10 6H14M6 8H18M16.6667 8L16.1991 15.0129C16.129 16.065 16.0939 16.5911 15.8667 16.99C15.6666 17.3412 15.3648 17.6235 15.0011 17.7998C14.588 18 14.0607 18 13.0062 18H10.9938C9.93927 18 9.41202 18 8.99889 17.7998C8.63517 17.6235 8.33339 17.3412 8.13332 16.99C7.90607 16.5911 7.871 16.065 7.80086 15.0129L7.33333 8M10.6667 11V14.3333M13.3333 11V14.3333" stroke="#667085" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" /> // <path d="M10 6H14M6 8H18M16.6667 8L16.1991 15.0129C16.129 16.065 16.0939 16.5911 15.8667 16.99C15.6666 17.3412 15.3648 17.6235 15.0011 17.7998C14.588 18 14.0607 18 13.0062 18H10.9938C9.93927 18 9.41202 18 8.99889 17.7998C8.63517 17.6235 8.33339 17.3412 8.13332 16.99C7.90607 16.5911 7.871 16.065 7.80086 15.0129L7.33333 8M10.6667 11V14.3333M13.3333 11V14.3333" stroke="#667085" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
...@@ -24,7 +24,8 @@ export interface ICardItemProps { ...@@ -24,7 +24,8 @@ export interface ICardItemProps {
const CardItem: FC<ICardItemProps> = ({ const CardItem: FC<ICardItemProps> = ({
className, className,
config, config,
onRemove onRemove,
readonly,
}) => { }) => {
const { t } = useTranslation() const { t } = useTranslation()
...@@ -44,7 +45,7 @@ const CardItem: FC<ICardItemProps> = ({ ...@@ -44,7 +45,7 @@ const CardItem: FC<ICardItemProps> = ({
</div> </div>
</div> </div>
<RemoveIcon className={`${s.deleteBtn} shrink-0`} onClick={() => onRemove(config.id)} /> {!readonly && <RemoveIcon className={`${s.deleteBtn} shrink-0`} onClick={() => onRemove(config.id)} />}
</div> </div>
) )
} }
......
...@@ -128,8 +128,12 @@ const SelectDataSet: FC<ISelectDataSetProps> = ({ ...@@ -128,8 +128,12 @@ const SelectDataSet: FC<ISelectDataSetProps> = ({
<div className='max-w-[200px] text-[13px] font-medium text-gray-800 overflow-hidden text-ellipsis whitespace-nowrap'>{item.name}</div> <div className='max-w-[200px] text-[13px] font-medium text-gray-800 overflow-hidden text-ellipsis whitespace-nowrap'>{item.name}</div>
</div> </div>
<div className='max-w-[140px] flex text-xs text-gray-500 overflow-hidden text-ellipsis whitespace-nowrap'> <div className='flex text-xs text-gray-500 overflow-hidden whitespace-nowrap'>
{formatNumber(item.word_count)} {t('appDebug.feature.dataSet.words')} · {formatNumber(item.document_count)} {t('appDebug.feature.dataSet.textBlocks')} <span className='max-w-[100px] overflow-hidden text-ellipsis whitespace-nowrap'>{formatNumber(item.word_count)}</span>
{t('appDebug.feature.dataSet.words')}
<span className='px-0.5'>·</span>
<span className='max-w-[100px] min-w-[8px] overflow-hidden text-ellipsis whitespace-nowrap'>{formatNumber(item.document_count)} </span>
{t('appDebug.feature.dataSet.textBlocks')}
</div> </div>
</div> </div>
))} ))}
......
...@@ -22,6 +22,7 @@ import type { ModelConfig as BackendModelConfig } from '@/types/app' ...@@ -22,6 +22,7 @@ import type { ModelConfig as BackendModelConfig } from '@/types/app'
import { promptVariablesToUserInputsForm } from '@/utils/model-config' import { promptVariablesToUserInputsForm } from '@/utils/model-config'
import TextGeneration from '@/app/components/app/text-generate/item' import TextGeneration from '@/app/components/app/text-generate/item'
import { IS_CE_EDITION } from '@/config' import { IS_CE_EDITION } from '@/config'
import { useProviderContext } from '@/context/provider-context'
type IDebug = { type IDebug = {
hasSetAPIKEY: boolean hasSetAPIKEY: boolean
...@@ -51,7 +52,7 @@ const Debug: FC<IDebug> = ({ ...@@ -51,7 +52,7 @@ const Debug: FC<IDebug> = ({
modelConfig, modelConfig,
completionParams, completionParams,
} = useContext(ConfigContext) } = useContext(ConfigContext)
const { currentProvider } = useProviderContext()
const [chatList, setChatList, getChatList] = useGetState<IChatItem[]>([]) const [chatList, setChatList, getChatList] = useGetState<IChatItem[]>([])
const chatListDomRef = useRef<HTMLDivElement>(null) const chatListDomRef = useRef<HTMLDivElement>(null)
useEffect(() => { useEffect(() => {
...@@ -389,7 +390,7 @@ const Debug: FC<IDebug> = ({ ...@@ -389,7 +390,7 @@ const Debug: FC<IDebug> = ({
}} }}
isShowSuggestion={doShowSuggestion} isShowSuggestion={doShowSuggestion}
suggestionList={suggestQuestions} suggestionList={suggestQuestions}
isShowSpeechToText={speechToTextConfig.enabled} isShowSpeechToText={speechToTextConfig.enabled && currentProvider?.provider_name === 'openai'}
/> />
</div> </div>
</div> </div>
......
...@@ -16,10 +16,10 @@ import dayjs from 'dayjs' ...@@ -16,10 +16,10 @@ import dayjs from 'dayjs'
import { createContext, useContext } from 'use-context-selector' import { createContext, useContext } from 'use-context-selector'
import classNames from 'classnames' import classNames from 'classnames'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { EditIconSolid } from '../chat'
import { randomString } from '../../app-sidebar/basic' import { randomString } from '../../app-sidebar/basic'
import s from './style.module.css' import s from './style.module.css'
import type { FeedbackFunc, Feedbacktype, IChatItem, SubmitAnnotationFunc } from '@/app/components/app/chat' import { EditIconSolid } from '@/app/components/app/chat/icon-component'
import type { FeedbackFunc, Feedbacktype, IChatItem, SubmitAnnotationFunc } from '@/app/components/app/chat/type'
import type { Annotation, ChatConversationFullDetailResponse, ChatConversationGeneralDetail, ChatConversationsResponse, ChatMessage, ChatMessagesRequest, CompletionConversationFullDetailResponse, CompletionConversationGeneralDetail, CompletionConversationsResponse } from '@/models/log' import type { Annotation, ChatConversationFullDetailResponse, ChatConversationGeneralDetail, ChatConversationsResponse, ChatMessage, ChatMessagesRequest, CompletionConversationFullDetailResponse, CompletionConversationGeneralDetail, CompletionConversationsResponse } from '@/models/log'
import type { App } from '@/types/app' import type { App } from '@/types/app'
import Loading from '@/app/components/base/loading' import Loading from '@/app/components/base/loading'
......
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="24" height="24" rx="6" fill="#CA9F7B"/>
<g clip-path="url(#clip0_7672_55906)">
<path d="M15.3843 6.43457H12.9687L17.3739 17.565H19.7896L15.3843 6.43457ZM8.40522 6.43457L4 17.565H6.4633L7.36417 15.2276H11.9729L12.8737 17.565H15.337L10.9318 6.43457H8.40522ZM8.16104 13.1605L9.66852 9.24883L11.176 13.1605H8.16104Z" fill="#191918"/>
</g>
<rect x="0.5" y="0.5" width="23" height="23" rx="5.5" stroke="black" stroke-opacity="0.05"/>
<defs>
<clipPath id="clip0_7672_55906">
<rect width="16" height="11.1304" fill="white" transform="translate(4 6.43457)"/>
</clipPath>
</defs>
</svg>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="24" height="24" rx="6" fill="#19C37D"/>
<path d="M19.6451 11.6028C19.8209 11.995 19.9325 12.4142 19.9781 12.8419C20.0221 13.2696 20.0001 13.7024 19.9088 14.1234C19.8192 14.5443 19.6637 14.9484 19.4473 15.3203C19.3053 15.5688 19.1379 15.8021 18.9452 16.0168C18.7542 16.2298 18.5412 16.4225 18.3096 16.5916C18.0763 16.7606 17.8278 16.9027 17.564 17.0193C17.302 17.1343 17.0281 17.2222 16.7475 17.2796C16.6156 17.6888 16.4195 18.0759 16.1659 18.4242C15.914 18.7724 15.6081 19.0784 15.2598 19.3303C14.9115 19.5839 14.5261 19.78 14.117 19.9118C13.7079 20.0454 13.2802 20.1113 12.8491 20.1113C12.5634 20.113 12.276 20.0826 11.9953 20.0251C11.7164 19.9659 11.4425 19.8763 11.1805 19.7597C10.9184 19.643 10.6699 19.4977 10.4383 19.3286C10.2084 19.1595 9.99541 18.9651 9.80606 18.7504C9.38342 18.8417 8.95064 18.8637 8.52293 18.8197C8.09522 18.7741 7.67596 18.6625 7.28206 18.4867C6.88985 18.3126 6.52638 18.0759 6.20687 17.7868C5.88735 17.4977 5.61517 17.1596 5.40047 16.7877C5.25677 16.5392 5.13843 16.2771 5.04883 16.005C4.95924 15.7328 4.90007 15.4522 4.86964 15.1665C4.83921 14.8824 4.8409 14.595 4.87133 14.3093C4.90176 14.0253 4.96431 13.7447 5.05391 13.4725C4.76651 13.153 4.52983 12.7895 4.35402 12.3973C4.17989 12.0034 4.06662 11.5859 4.02267 11.1581C3.97702 10.7304 4.00069 10.2976 4.09029 9.8767C4.17989 9.45575 4.33542 9.05171 4.55181 8.67978C4.69382 8.43127 4.86118 8.19628 5.05222 7.98327C5.24325 7.77026 5.45795 7.57754 5.68956 7.40848C5.92116 7.23943 6.17136 7.09573 6.4334 6.98077C6.69713 6.86412 6.971 6.77791 7.25163 6.72043C7.38349 6.30962 7.5796 5.92417 7.83149 5.57592C8.08508 5.22766 8.39107 4.92167 8.73932 4.66809C9.08758 4.4162 9.47302 4.22009 9.88214 4.08654C10.2913 3.95467 10.719 3.88705 11.1501 3.88874C11.4358 3.88705 11.7232 3.91579 12.0038 3.97496C12.2844 4.03413 12.5583 4.12204 12.8203 4.23869C13.0824 4.35703 13.3309 4.50072 13.5625 4.66978C13.7941 4.84053 14.0071 5.03325 14.1964 5.24795C14.6174 5.15835 15.0502 5.13637 15.4779 5.18033C15.9056 5.22428 16.3232 5.33755 16.7171 5.51168C17.1093 5.6875 17.4727 5.92248 17.7923 6.21157C18.1118 6.49896 18.384 6.83538 18.5987 7.209C18.7423 7.45582 18.8607 7.71786 18.9503 7.99173C19.0399 8.26391 19.1007 8.54454 19.1295 8.83024C19.1599 9.11595 19.1599 9.40334 19.1278 9.68905C19.0974 9.97475 19.0348 10.2554 18.9452 10.5276C19.2343 10.8471 19.4693 11.2089 19.6451 11.6028ZM14.0122 18.8197C14.3807 18.6676 14.7154 18.4428 14.9978 18.1604C15.2801 17.8781 15.5049 17.5434 15.6571 17.1731C15.8092 16.8046 15.8887 16.409 15.8887 16.01V12.2401C15.8876 12.2367 15.8864 12.2328 15.8853 12.2283C15.8842 12.2249 15.8825 12.2215 15.8802 12.2181C15.878 12.2147 15.8752 12.2119 15.8718 12.2097C15.8684 12.2063 15.865 12.204 15.8616 12.2029L14.4974 11.4151V15.9695C14.4974 16.0151 14.4906 16.0624 14.4788 16.1064C14.4669 16.152 14.45 16.1943 14.4264 16.2349C14.4027 16.2755 14.3756 16.3126 14.3418 16.3448C14.309 16.3775 14.272 16.4059 14.2319 16.4293L11.0013 18.294C10.9742 18.3109 10.9286 18.3346 10.9049 18.3481C11.0385 18.4613 11.1839 18.5611 11.336 18.649C11.4899 18.7369 11.6488 18.8113 11.8144 18.8722C11.9801 18.9313 12.1509 18.977 12.3233 19.0074C12.4974 19.0378 12.6732 19.053 12.8491 19.053C13.248 19.053 13.6436 18.9736 14.0122 18.8197ZM6.31844 16.2602C6.51962 16.6068 6.78504 16.9077 7.10117 17.1512C7.419 17.3946 7.77908 17.5721 8.16453 17.6752C8.54998 17.7784 8.95233 17.8054 9.34792 17.753C9.74351 17.7006 10.1239 17.5721 10.4705 17.3726L13.7366 15.4877L13.7451 15.4792C13.7473 15.477 13.749 15.4736 13.7501 15.4691C13.7524 15.4657 13.7541 15.4623 13.7552 15.4589V13.8698L9.81283 16.1504C9.77225 16.174 9.72999 16.1909 9.68603 16.2045C9.64039 16.2163 9.59474 16.2214 9.54741 16.2214C9.50176 16.2214 9.45612 16.2163 9.41047 16.2045C9.36652 16.1909 9.32256 16.174 9.28199 16.1504L6.05133 14.284C6.0226 14.2671 5.98033 14.2417 5.95666 14.2265C5.92623 14.4006 5.91102 14.5764 5.91102 14.7523C5.91102 14.9281 5.92792 15.1039 5.95835 15.278C5.98878 15.4505 6.03612 15.6212 6.09529 15.7869C6.15615 15.9526 6.23053 16.1115 6.31844 16.2636V16.2602ZM5.46978 9.21062C5.2703 9.55718 5.14182 9.93925 5.08941 10.3348C5.037 10.7304 5.06405 11.1311 5.16717 11.5182C5.2703 11.9037 5.44781 12.2638 5.69125 12.5816C5.93469 12.8977 6.2373 13.1631 6.58217 13.3626L9.84664 15.2493C9.85002 15.2504 9.85396 15.2515 9.85847 15.2527H9.8703C9.87481 15.2527 9.87876 15.2515 9.88214 15.2493C9.88552 15.2482 9.8889 15.2465 9.89228 15.2442L11.2616 14.453L7.31925 12.1775C7.28037 12.1539 7.24318 12.1251 7.20937 12.093C7.17661 12.0602 7.1482 12.0232 7.12484 11.9831C7.10286 11.9426 7.08427 11.9003 7.07243 11.8547C7.0606 11.8107 7.05384 11.7651 7.05553 11.7177V7.87846C6.88985 7.93932 6.72925 8.0137 6.5771 8.10161C6.42495 8.19121 6.28125 8.29265 6.14601 8.40591C6.01245 8.51918 5.88735 8.64428 5.77408 8.77953C5.66082 8.91308 5.56107 9.05847 5.47316 9.21062H5.46978ZM16.6832 11.8208C16.7238 11.8445 16.761 11.8716 16.7948 11.9054C16.8269 11.9375 16.8557 11.9747 16.8794 12.0153C16.9013 12.0558 16.9199 12.0998 16.9318 12.1437C16.9419 12.1894 16.9487 12.235 16.947 12.2824V16.1216C17.4896 15.9221 17.963 15.5722 18.3129 15.1124C18.6646 14.6525 18.8759 14.1031 18.9249 13.5283C18.974 12.9535 18.859 12.3753 18.5919 11.8631C18.3248 11.3509 17.9174 10.9248 17.417 10.6374L14.1525 8.75079C14.1491 8.74966 14.1452 8.74853 14.1407 8.74741H14.1288C14.1254 8.74853 14.1215 8.74966 14.117 8.75079C14.1136 8.75191 14.1102 8.7536 14.1068 8.75586L12.7443 9.54366L16.6866 11.8208H16.6832ZM18.0441 9.77526H18.0425V9.77695L18.0441 9.77526ZM18.0425 9.77357C18.1405 9.20555 18.0746 8.62061 17.8514 8.08809C17.63 7.55556 17.2597 7.09742 16.7864 6.76607C16.313 6.43641 15.7551 6.24707 15.1787 6.22171C14.6005 6.19804 14.0291 6.33836 13.5287 6.62575L10.2642 8.51073C10.2608 8.51298 10.258 8.5158 10.2558 8.51918L10.249 8.52932C10.2479 8.5327 10.2467 8.53665 10.2456 8.54116C10.2445 8.54454 10.2439 8.54848 10.2439 8.55299V10.1286L14.1863 7.85141C14.2269 7.82774 14.2708 7.81084 14.3148 7.79731C14.3604 7.78548 14.4061 7.78041 14.4517 7.78041C14.499 7.78041 14.5447 7.78548 14.5903 7.79731C14.6343 7.81084 14.6766 7.82774 14.7171 7.85141L17.9478 9.71778C17.9765 9.73469 18.0188 9.75836 18.0425 9.77357ZM9.50007 8.02892C9.50007 7.98327 9.50683 7.93763 9.51867 7.89198C9.5305 7.84803 9.54741 7.80407 9.57108 7.7635C9.59474 7.72462 9.62179 7.68743 9.6556 7.65361C9.68772 7.62149 9.72492 7.59275 9.76549 7.57078L12.9961 5.70609C13.0266 5.6875 13.0688 5.66383 13.0925 5.65199C12.6496 5.28176 12.1086 5.04508 11.5355 4.97239C10.9624 4.89801 10.3809 4.9893 9.85847 5.23443C9.3344 5.47956 8.89147 5.87008 8.5821 6.35696C8.27273 6.84553 8.10874 7.41017 8.10874 7.98834V11.7583C8.10987 11.7628 8.111 11.7667 8.11212 11.7701C8.11325 11.7735 8.11494 11.7769 8.1172 11.7803C8.11945 11.7836 8.12227 11.787 8.12565 11.7904C8.1279 11.7927 8.13128 11.7949 8.13579 11.7972L9.50007 12.585V8.02892ZM10.2405 13.011L11.997 14.0253L13.7535 13.011V10.984L11.9987 9.96968L10.2422 10.984L10.2405 13.011Z" fill="white"/>
<rect x="0.5" y="0.5" width="23" height="23" rx="5.5" stroke="black" stroke-opacity="0.05"/>
</svg>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="24" height="24" rx="6" fill="#AB68FF"/>
<path d="M19.6451 11.6028C19.8209 11.995 19.9325 12.4142 19.9781 12.8419C20.0221 13.2696 20.0001 13.7024 19.9088 14.1234C19.8192 14.5443 19.6637 14.9484 19.4473 15.3203C19.3053 15.5688 19.1379 15.8021 18.9452 16.0168C18.7542 16.2298 18.5412 16.4225 18.3096 16.5916C18.0763 16.7606 17.8278 16.9027 17.564 17.0193C17.302 17.1343 17.0281 17.2222 16.7475 17.2796C16.6156 17.6888 16.4195 18.0759 16.1659 18.4242C15.914 18.7724 15.6081 19.0784 15.2598 19.3303C14.9115 19.5839 14.5261 19.78 14.117 19.9118C13.7079 20.0454 13.2802 20.1113 12.8491 20.1113C12.5634 20.113 12.276 20.0826 11.9953 20.0251C11.7164 19.9659 11.4425 19.8763 11.1805 19.7597C10.9184 19.643 10.6699 19.4977 10.4383 19.3286C10.2084 19.1595 9.99541 18.9651 9.80606 18.7504C9.38342 18.8417 8.95064 18.8637 8.52293 18.8197C8.09522 18.7741 7.67596 18.6625 7.28206 18.4867C6.88985 18.3126 6.52638 18.0759 6.20687 17.7868C5.88735 17.4977 5.61517 17.1596 5.40047 16.7877C5.25677 16.5392 5.13843 16.2771 5.04883 16.005C4.95924 15.7328 4.90007 15.4522 4.86964 15.1665C4.83921 14.8824 4.8409 14.595 4.87133 14.3093C4.90176 14.0253 4.96431 13.7447 5.05391 13.4725C4.76651 13.153 4.52983 12.7895 4.35402 12.3973C4.17989 12.0034 4.06662 11.5859 4.02267 11.1581C3.97702 10.7304 4.00069 10.2976 4.09029 9.8767C4.17989 9.45575 4.33542 9.05171 4.55181 8.67978C4.69382 8.43127 4.86118 8.19628 5.05222 7.98327C5.24325 7.77026 5.45795 7.57754 5.68956 7.40848C5.92116 7.23943 6.17136 7.09573 6.4334 6.98077C6.69713 6.86412 6.971 6.77791 7.25163 6.72043C7.38349 6.30962 7.5796 5.92417 7.83149 5.57592C8.08508 5.22766 8.39107 4.92167 8.73932 4.66809C9.08758 4.4162 9.47302 4.22009 9.88214 4.08654C10.2913 3.95467 10.719 3.88705 11.1501 3.88874C11.4358 3.88705 11.7232 3.91579 12.0038 3.97496C12.2844 4.03413 12.5583 4.12204 12.8203 4.23869C13.0824 4.35703 13.3309 4.50072 13.5625 4.66978C13.7941 4.84053 14.0071 5.03325 14.1964 5.24795C14.6174 5.15835 15.0502 5.13637 15.4779 5.18033C15.9056 5.22428 16.3232 5.33755 16.7171 5.51168C17.1093 5.6875 17.4727 5.92248 17.7923 6.21157C18.1118 6.49896 18.384 6.83538 18.5987 7.209C18.7423 7.45582 18.8607 7.71786 18.9503 7.99173C19.0399 8.26391 19.1007 8.54454 19.1295 8.83024C19.1599 9.11595 19.1599 9.40334 19.1278 9.68905C19.0974 9.97475 19.0348 10.2554 18.9452 10.5276C19.2343 10.8471 19.4693 11.2089 19.6451 11.6028ZM14.0122 18.8197C14.3807 18.6676 14.7154 18.4428 14.9978 18.1604C15.2801 17.8781 15.5049 17.5434 15.6571 17.1731C15.8092 16.8046 15.8887 16.409 15.8887 16.01V12.2401C15.8876 12.2367 15.8864 12.2328 15.8853 12.2283C15.8842 12.2249 15.8825 12.2215 15.8802 12.2181C15.878 12.2147 15.8752 12.2119 15.8718 12.2097C15.8684 12.2063 15.865 12.204 15.8616 12.2029L14.4974 11.4151V15.9695C14.4974 16.0151 14.4906 16.0624 14.4788 16.1064C14.4669 16.152 14.45 16.1943 14.4264 16.2349C14.4027 16.2755 14.3756 16.3126 14.3418 16.3448C14.309 16.3775 14.272 16.4059 14.2319 16.4293L11.0013 18.294C10.9742 18.3109 10.9286 18.3346 10.9049 18.3481C11.0385 18.4613 11.1839 18.5611 11.336 18.649C11.4899 18.7369 11.6488 18.8113 11.8144 18.8722C11.9801 18.9313 12.1509 18.977 12.3233 19.0074C12.4974 19.0378 12.6732 19.053 12.8491 19.053C13.248 19.053 13.6436 18.9736 14.0122 18.8197ZM6.31844 16.2602C6.51962 16.6068 6.78504 16.9077 7.10117 17.1512C7.419 17.3946 7.77908 17.5721 8.16453 17.6752C8.54998 17.7784 8.95233 17.8054 9.34792 17.753C9.74351 17.7006 10.1239 17.5721 10.4705 17.3726L13.7366 15.4877L13.7451 15.4792C13.7473 15.477 13.749 15.4736 13.7501 15.4691C13.7524 15.4657 13.7541 15.4623 13.7552 15.4589V13.8698L9.81283 16.1504C9.77225 16.174 9.72999 16.1909 9.68603 16.2045C9.64039 16.2163 9.59474 16.2214 9.54741 16.2214C9.50176 16.2214 9.45612 16.2163 9.41047 16.2045C9.36652 16.1909 9.32256 16.174 9.28199 16.1504L6.05133 14.284C6.0226 14.2671 5.98033 14.2417 5.95666 14.2265C5.92623 14.4006 5.91102 14.5764 5.91102 14.7523C5.91102 14.9281 5.92792 15.1039 5.95835 15.278C5.98878 15.4505 6.03612 15.6212 6.09529 15.7869C6.15615 15.9526 6.23053 16.1115 6.31844 16.2636V16.2602ZM5.46978 9.21062C5.2703 9.55718 5.14182 9.93925 5.08941 10.3348C5.037 10.7304 5.06405 11.1311 5.16717 11.5182C5.2703 11.9037 5.44781 12.2638 5.69125 12.5816C5.93469 12.8977 6.2373 13.1631 6.58217 13.3626L9.84664 15.2493C9.85002 15.2504 9.85396 15.2515 9.85847 15.2527H9.8703C9.87481 15.2527 9.87876 15.2515 9.88214 15.2493C9.88552 15.2482 9.8889 15.2465 9.89228 15.2442L11.2616 14.453L7.31925 12.1775C7.28037 12.1539 7.24318 12.1251 7.20937 12.093C7.17661 12.0602 7.1482 12.0232 7.12484 11.9831C7.10286 11.9426 7.08427 11.9003 7.07243 11.8547C7.0606 11.8107 7.05384 11.7651 7.05553 11.7177V7.87846C6.88985 7.93932 6.72925 8.0137 6.5771 8.10161C6.42495 8.19121 6.28125 8.29265 6.14601 8.40591C6.01245 8.51918 5.88735 8.64428 5.77408 8.77953C5.66082 8.91308 5.56107 9.05847 5.47316 9.21062H5.46978ZM16.6832 11.8208C16.7238 11.8445 16.761 11.8716 16.7948 11.9054C16.8269 11.9375 16.8557 11.9747 16.8794 12.0153C16.9013 12.0558 16.9199 12.0998 16.9318 12.1437C16.9419 12.1894 16.9487 12.235 16.947 12.2824V16.1216C17.4896 15.9221 17.963 15.5722 18.3129 15.1124C18.6646 14.6525 18.8759 14.1031 18.9249 13.5283C18.974 12.9535 18.859 12.3753 18.5919 11.8631C18.3248 11.3509 17.9174 10.9248 17.417 10.6374L14.1525 8.75079C14.1491 8.74966 14.1452 8.74853 14.1407 8.74741H14.1288C14.1254 8.74853 14.1215 8.74966 14.117 8.75079C14.1136 8.75191 14.1102 8.7536 14.1068 8.75586L12.7443 9.54366L16.6866 11.8208H16.6832ZM18.0441 9.77526H18.0425V9.77695L18.0441 9.77526ZM18.0425 9.77357C18.1405 9.20555 18.0746 8.62061 17.8514 8.08809C17.63 7.55556 17.2597 7.09742 16.7864 6.76607C16.313 6.43641 15.7551 6.24707 15.1787 6.22171C14.6005 6.19804 14.0291 6.33836 13.5287 6.62575L10.2642 8.51073C10.2608 8.51298 10.258 8.5158 10.2558 8.51918L10.249 8.52932C10.2479 8.5327 10.2467 8.53665 10.2456 8.54116C10.2445 8.54454 10.2439 8.54848 10.2439 8.55299V10.1286L14.1863 7.85141C14.2269 7.82774 14.2708 7.81084 14.3148 7.79731C14.3604 7.78548 14.4061 7.78041 14.4517 7.78041C14.499 7.78041 14.5447 7.78548 14.5903 7.79731C14.6343 7.81084 14.6766 7.82774 14.7171 7.85141L17.9478 9.71778C17.9765 9.73469 18.0188 9.75836 18.0425 9.77357ZM9.50007 8.02892C9.50007 7.98327 9.50683 7.93763 9.51867 7.89198C9.5305 7.84803 9.54741 7.80407 9.57108 7.7635C9.59474 7.72462 9.62179 7.68743 9.6556 7.65361C9.68772 7.62149 9.72492 7.59275 9.76549 7.57078L12.9961 5.70609C13.0266 5.6875 13.0688 5.66383 13.0925 5.65199C12.6496 5.28176 12.1086 5.04508 11.5355 4.97239C10.9624 4.89801 10.3809 4.9893 9.85847 5.23443C9.3344 5.47956 8.89147 5.87008 8.5821 6.35696C8.27273 6.84553 8.10874 7.41017 8.10874 7.98834V11.7583C8.10987 11.7628 8.111 11.7667 8.11212 11.7701C8.11325 11.7735 8.11494 11.7769 8.1172 11.7803C8.11945 11.7836 8.12227 11.787 8.12565 11.7904C8.1279 11.7927 8.13128 11.7949 8.13579 11.7972L9.50007 12.585V8.02892ZM10.2405 13.011L11.997 14.0253L13.7535 13.011V10.984L11.9987 9.96968L10.2422 10.984L10.2405 13.011Z" fill="white"/>
<rect x="0.5" y="0.5" width="23" height="23" rx="5.5" stroke="black" stroke-opacity="0.05"/>
</svg>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.3332 4L5.99984 11.3333L2.6665 8" stroke="#155EEF" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M22.501 12.2331C22.501 11.3698 22.4296 10.7398 22.2748 10.0864H12.2153V13.983H18.12C18.001 14.9514 17.3582 16.4097 15.9296 17.3897L15.9096 17.5202L19.0902 19.9349L19.3106 19.9564C21.3343 18.1247 22.501 15.4297 22.501 12.2331Z" fill="#4285F4"/>
<path d="M12.2147 22.5001C15.1075 22.5001 17.5361 21.5667 19.3099 19.9567L15.929 17.39C15.0242 18.0083 13.8099 18.44 12.2147 18.44C9.38142 18.44 6.97669 16.6083 6.11947 14.0767L5.99382 14.0871L2.68656 16.5955L2.64331 16.7133C4.40519 20.1433 8.02423 22.5001 12.2147 22.5001Z" fill="#34A853"/>
<path d="M6.11997 14.0765C5.89379 13.4232 5.76289 12.7231 5.76289 11.9998C5.76289 11.2764 5.89379 10.5765 6.10807 9.92313L6.10208 9.78398L2.75337 7.23535L2.64381 7.28642C1.91765 8.70977 1.50098 10.3081 1.50098 11.9998C1.50098 13.6915 1.91765 15.2897 2.64381 16.7131L6.11997 14.0765Z" fill="#FBBC05"/>
<path d="M12.2148 5.55997C14.2267 5.55997 15.5838 6.41163 16.3576 7.12335L19.3814 4.23C17.5243 2.53834 15.1076 1.5 12.2148 1.5C8.02426 1.5 4.4052 3.85665 2.64331 7.28662L6.10759 9.92332C6.97672 7.39166 9.38146 5.55997 12.2148 5.55997Z" fill="#EB4335"/>
</svg>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.59235 3.32566C10.3587 3.11341 11.1661 3 12 3C13.962 3 15.7773 3.62779 17.2561 4.69345C16.4693 5.21349 15.8824 5.77819 15.4756 6.38193C14.854 7.30445 14.6947 8.25844 14.8234 9.12887C14.9484 9.97416 15.3366 10.696 15.7446 11.2301C16.1402 11.7479 16.6256 12.181 17.0531 12.3946C18.1294 12.9327 19.3714 13.2022 20.2999 13.341C21.1399 13.4667 22.9206 13.8871 22.9865 12.5492C22.9955 12.3672 23 12.1841 23 12C23 5.92487 18.0751 1 12 1C5.92487 1 1 5.92487 1 12C1 18.0751 5.92487 23 12 23C12.1841 23 12.3672 22.9955 12.5492 22.9865C13.1008 22.9593 13.526 22.4902 13.4988 21.9385C13.4716 21.3869 13.0024 20.9618 12.4508 20.9889C12.3015 20.9963 12.1512 21 12 21C8.49063 21 5.45038 18.9914 3.96619 16.0611L4.93474 15.502L8.50745 16.1706C9.43309 16.3439 10.2876 15.6313 10.2834 14.6896L10.2694 11.5365L12.0952 8.41051C12.3911 7.90404 12.3646 7.27161 12.0274 6.79167L9.59235 3.32566Z" fill="#444CE7"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.9456 12.6561C13.5777 12.5165 13.1621 12.6057 12.8839 12.884C12.6056 13.1623 12.5164 13.5778 12.656 13.9458L15.8228 22.2945C15.969 22.68 16.3367 22.9362 16.7489 22.9399C17.1611 22.9435 17.5333 22.6938 17.6863 22.3111L19.007 19.0071L22.311 17.6865C22.6937 17.5334 22.9434 17.1612 22.9397 16.749C22.9361 16.3368 22.6799 15.9691 22.2944 15.8229L13.9456 12.6561Z" fill="#444CE7"/>
</svg>
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M23.8431 5.0001H19.2179H19.0609V5.15706V5.66001V5.81696H19.2179H19.5393C19.9131 5.81696 20.2502 6.00882 20.4411 6.33021C20.632 6.65161 20.6392 7.0394 20.4603 7.36765L15.3174 16.8077L12.9751 11.2238L15.1813 7.17527C15.6379 6.33743 16.5143 5.81696 17.4684 5.81696H17.5726H17.7296V5.66001V5.15706V5.0001H17.5726H12.9474H12.7905V5.15706V5.66001V5.81696H12.9474H13.2688C13.6426 5.81696 13.9797 6.00882 14.1706 6.33021C14.3615 6.65161 14.3687 7.0394 14.1899 7.36765L12.5896 10.305L11.1634 6.9051C11.0601 6.65867 11.0856 6.38965 11.2336 6.16714C11.3816 5.94462 11.6197 5.81696 11.887 5.81696H12.2526H12.4095V5.66001V5.15706V5.0001H12.2526H6.72092H6.56396V5.15706V5.66001V5.81696H6.72092H6.79699C7.88821 5.81696 8.866 6.46719 9.28817 7.47344L11.3954 12.497L9.04698 16.8077L4.89304 6.9051C4.78966 6.65867 4.81525 6.38965 4.9632 6.16714C5.11116 5.94462 5.34932 5.81696 5.61657 5.81696H6.17832H6.33527V5.66001V5.15706V5.0001H6.17832H0.156957H0V5.15706V5.66001V5.81696H0.156957H0.52654C1.61776 5.81696 2.59561 6.46719 3.01772 7.47344L7.80628 18.889C7.89004 19.0887 8.08425 19.2177 8.30111 19.2177C8.50014 19.2177 8.67588 19.1131 8.77125 18.9381L9.39589 17.7918L11.7807 13.4155L14.0767 18.889C14.1604 19.0886 14.3547 19.2176 14.5715 19.2176C14.7705 19.2176 14.9463 19.1131 15.0417 18.938L15.6663 17.7917L21.4517 7.17517C21.9083 6.33733 22.7847 5.81686 23.7388 5.81686H23.843H24V5.6599V5.15696V5H23.8431V5.0001Z" fill="#222A30"/>
</svg>
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_7847_32895)">
<path d="M10.5 2.5C10.5 3.32843 8.48528 4 6 4C3.51472 4 1.5 3.32843 1.5 2.5M10.5 2.5C10.5 1.67157 8.48528 1 6 1C3.51472 1 1.5 1.67157 1.5 2.5M10.5 2.5V9.5C10.5 10.33 8.5 11 6 11C3.5 11 1.5 10.33 1.5 9.5V2.5M10.5 6C10.5 6.83 8.5 7.5 6 7.5C3.5 7.5 1.5 6.83 1.5 6" stroke="#667085" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_7847_32895">
<rect width="12" height="12" fill="white"/>
</clipPath>
</defs>
</svg>
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_7998_4025)">
<path d="M6 1.125V2.375M6 9V11M2.875 6H1.125M10.625 6H9.875M9.22855 9.22855L8.875 8.875M9.33211 2.70789L8.625 3.415M2.46079 9.53921L3.875 8.125M2.56434 2.60434L3.625 3.665" stroke="#667085" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_7998_4025">
<rect width="12" height="12" fill="white"/>
</clipPath>
</defs>
</svg>
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_7847_32899)">
<path d="M10.5 10.5L8.75005 8.75M10 5.75C10 8.09721 8.09721 10 5.75 10C3.40279 10 1.5 8.09721 1.5 5.75C1.5 3.40279 3.40279 1.5 5.75 1.5C8.09721 1.5 10 3.40279 10 5.75Z" stroke="#667085" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_7847_32899">
<rect width="12" height="12" fill="white"/>
</clipPath>
</defs>
</svg>
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 6C4 5.72386 4.22386 5.5 4.5 5.5L10.5 5.5C10.7761 5.5 11 5.72386 11 6C11 6.27614 10.7761 6.5 10.5 6.5L4.5 6.5C4.22386 6.5 4 6.27614 4 6Z" fill="#667085"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 3C4 2.72386 4.22386 2.5 4.5 2.5L10.5 2.5C10.7761 2.5 11 2.72386 11 3C11 3.27614 10.7761 3.5 10.5 3.5L4.5 3.5C4.22386 3.5 4 3.27614 4 3Z" fill="#667085"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M4 9C4 8.72386 4.22386 8.5 4.5 8.5L10.5 8.5C10.7761 8.5 11 8.72386 11 9C11 9.27614 10.7761 9.5 10.5 9.5L4.5 9.5C4.22386 9.5 4 9.27614 4 9Z" fill="#667085"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M1 6C1 5.44772 1.44772 5 2 5C2.55228 5 3 5.44772 3 6C3 6.55228 2.55228 7 2 7C1.44772 7 1 6.55228 1 6Z" fill="#667085"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M1 3C1 2.44772 1.44772 2 2 2C2.55228 2 3 2.44772 3 3C3 3.55228 2.55228 4 2 4C1.44772 4 1 3.55228 1 3Z" fill="#667085"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M1 9C1 8.44772 1.44772 8 2 8C2.55228 8 3 8.44772 3 9C3 9.55228 2.55228 10 2 10C1.44772 10 1 9.55228 1 9Z" fill="#667085"/>
</svg>
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_7847_32887)">
<path d="M4.5 1.75V1M2.53033 2.53033L2 2M2.53033 6.5L2 7.03033M6.5 2.53033L7.03033 2M1.75 4.5H1M7.93224 8.09479L6.68637 10.4085C6.54404 10.6728 6.47287 10.805 6.38725 10.8384C6.31295 10.8674 6.22926 10.8592 6.16199 10.8164C6.08447 10.767 6.04028 10.6235 5.95191 10.3366L4.22259 4.72263C4.1504 4.48825 4.1143 4.37107 4.14335 4.29192C4.16865 4.22298 4.22298 4.16865 4.29192 4.14335C4.37107 4.1143 4.48825 4.1504 4.72262 4.2226L10.3366 5.95192C10.6235 6.0403 10.767 6.08449 10.8164 6.16201C10.8592 6.22928 10.8674 6.31297 10.8384 6.38727C10.805 6.47289 10.6728 6.54406 10.4085 6.68639L8.09479 7.93224C8.05551 7.95339 8.03587 7.96396 8.01868 7.97755C8.00341 7.98961 7.98961 8.00341 7.97755 8.01868C7.96396 8.03587 7.95339 8.05551 7.93224 8.09479Z" stroke="#667085" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
</g>
<defs>
<clipPath id="clip0_7847_32887">
<rect width="12" height="12" fill="white"/>
</clipPath>
</defs>
</svg>
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="link-external-02">
<path id="Icon" d="M10.5 4.5L10.5 1.5M10.5 1.5H7.49999M10.5 1.5L6 6M5 1.5H3.9C3.05992 1.5 2.63988 1.5 2.31901 1.66349C2.03677 1.8073 1.8073 2.03677 1.66349 2.31901C1.5 2.63988 1.5 3.05992 1.5 3.9V8.1C1.5 8.94008 1.5 9.36012 1.66349 9.68099C1.8073 9.96323 2.03677 10.1927 2.31901 10.3365C2.63988 10.5 3.05992 10.5 3.9 10.5H8.1C8.94008 10.5 9.36012 10.5 9.68099 10.3365C9.96323 10.1927 10.1927 9.96323 10.3365 9.68099C10.5 9.36012 10.5 8.94008 10.5 8.1V7" stroke="#155EEF" stroke-linecap="round" stroke-linejoin="round"/>
</g>
</svg>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="alert-circle">
<path id="Solid" fill-rule="evenodd" clip-rule="evenodd" d="M8 0.666626C3.94992 0.666626 0.666672 3.94987 0.666672 7.99996C0.666672 12.05 3.94992 15.3333 8 15.3333C12.0501 15.3333 15.3333 12.05 15.3333 7.99996C15.3333 3.94987 12.0501 0.666626 8 0.666626ZM8.66667 5.33329C8.66667 4.9651 8.36819 4.66663 8 4.66663C7.63181 4.66663 7.33334 4.9651 7.33334 5.33329V7.99996C7.33334 8.36815 7.63181 8.66663 8 8.66663C8.36819 8.66663 8.66667 8.36815 8.66667 7.99996V5.33329ZM8 9.99996C7.63181 9.99996 7.33334 10.2984 7.33334 10.6666C7.33334 11.0348 7.63181 11.3333 8 11.3333H8.00667C8.37486 11.3333 8.67334 11.0348 8.67334 10.6666C8.67334 10.2984 8.37486 9.99996 8.00667 9.99996H8Z" fill="#D92D20"/>
</g>
</svg>
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="check-circle">
<path id="Solid" fill-rule="evenodd" clip-rule="evenodd" d="M8 0.666626C3.94992 0.666626 0.666672 3.94987 0.666672 7.99996C0.666672 12.05 3.94992 15.3333 8 15.3333C12.0501 15.3333 15.3333 12.05 15.3333 7.99996C15.3333 3.94987 12.0501 0.666626 8 0.666626ZM11.4714 6.47136C11.7318 6.21101 11.7318 5.7889 11.4714 5.52855C11.2111 5.26821 10.7889 5.26821 10.5286 5.52855L7 9.05715L5.47141 7.52855C5.21106 7.2682 4.78895 7.2682 4.5286 7.52855C4.26825 7.7889 4.26825 8.21101 4.5286 8.47136L6.5286 10.4714C6.78895 10.7317 7.21106 10.7317 7.47141 10.4714L11.4714 6.47136Z" fill="#039855"/>
</g>
</svg>
{
"icon": {
"type": "element",
"isRootNode": true,
"name": "svg",
"attributes": {
"width": "24",
"height": "24",
"viewBox": "0 0 24 24",
"fill": "none",
"xmlns": "http://www.w3.org/2000/svg"
},
"children": [
{
"type": "element",
"name": "rect",
"attributes": {
"width": "24",
"height": "24",
"rx": "6",
"fill": "#CA9F7B"
},
"children": []
},
{
"type": "element",
"name": "g",
"attributes": {
"clip-path": "url(#clip0_7672_55906)"
},
"children": [
{
"type": "element",
"name": "path",
"attributes": {
"d": "M15.3843 6.43457H12.9687L17.3739 17.565H19.7896L15.3843 6.43457ZM8.40522 6.43457L4 17.565H6.4633L7.36417 15.2276H11.9729L12.8737 17.565H15.337L10.9318 6.43457H8.40522ZM8.16104 13.1605L9.66852 9.24883L11.176 13.1605H8.16104Z",
"fill": "#191918"
},
"children": []
}
]
},
{
"type": "element",
"name": "rect",
"attributes": {
"x": "0.5",
"y": "0.5",
"width": "23",
"height": "23",
"rx": "5.5",
"stroke": "black",
"stroke-opacity": "0.05"
},
"children": []
},
{
"type": "element",
"name": "defs",
"attributes": {},
"children": [
{
"type": "element",
"name": "clipPath",
"attributes": {
"id": "clip0_7672_55906"
},
"children": [
{
"type": "element",
"name": "rect",
"attributes": {
"width": "16",
"height": "11.1304",
"fill": "white",
"transform": "translate(4 6.43457)"
},
"children": []
}
]
}
]
}
]
},
"name": "Anthropic"
}
\ No newline at end of file
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import * as React from 'react'
import data from './Anthropic.json'
import IconBase from '@/app/components/base/icons/IconBase'
import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
props,
ref,
) => <IconBase {...props} ref={ref} data={data as IconData} />)
export default Icon
{
"icon": {
"type": "element",
"isRootNode": true,
"name": "svg",
"attributes": {
"width": "24",
"height": "24",
"viewBox": "0 0 24 24",
"fill": "none",
"xmlns": "http://www.w3.org/2000/svg"
},
"children": [
{
"type": "element",
"name": "rect",
"attributes": {
"width": "24",
"height": "24",
"rx": "6",
"fill": "#19C37D"
},
"children": []
},
{
"type": "element",
"name": "path",
"attributes": {
"d": "M19.6451 11.6028C19.8209 11.995 19.9325 12.4142 19.9781 12.8419C20.0221 13.2696 20.0001 13.7024 19.9088 14.1234C19.8192 14.5443 19.6637 14.9484 19.4473 15.3203C19.3053 15.5688 19.1379 15.8021 18.9452 16.0168C18.7542 16.2298 18.5412 16.4225 18.3096 16.5916C18.0763 16.7606 17.8278 16.9027 17.564 17.0193C17.302 17.1343 17.0281 17.2222 16.7475 17.2796C16.6156 17.6888 16.4195 18.0759 16.1659 18.4242C15.914 18.7724 15.6081 19.0784 15.2598 19.3303C14.9115 19.5839 14.5261 19.78 14.117 19.9118C13.7079 20.0454 13.2802 20.1113 12.8491 20.1113C12.5634 20.113 12.276 20.0826 11.9953 20.0251C11.7164 19.9659 11.4425 19.8763 11.1805 19.7597C10.9184 19.643 10.6699 19.4977 10.4383 19.3286C10.2084 19.1595 9.99541 18.9651 9.80606 18.7504C9.38342 18.8417 8.95064 18.8637 8.52293 18.8197C8.09522 18.7741 7.67596 18.6625 7.28206 18.4867C6.88985 18.3126 6.52638 18.0759 6.20687 17.7868C5.88735 17.4977 5.61517 17.1596 5.40047 16.7877C5.25677 16.5392 5.13843 16.2771 5.04883 16.005C4.95924 15.7328 4.90007 15.4522 4.86964 15.1665C4.83921 14.8824 4.8409 14.595 4.87133 14.3093C4.90176 14.0253 4.96431 13.7447 5.05391 13.4725C4.76651 13.153 4.52983 12.7895 4.35402 12.3973C4.17989 12.0034 4.06662 11.5859 4.02267 11.1581C3.97702 10.7304 4.00069 10.2976 4.09029 9.8767C4.17989 9.45575 4.33542 9.05171 4.55181 8.67978C4.69382 8.43127 4.86118 8.19628 5.05222 7.98327C5.24325 7.77026 5.45795 7.57754 5.68956 7.40848C5.92116 7.23943 6.17136 7.09573 6.4334 6.98077C6.69713 6.86412 6.971 6.77791 7.25163 6.72043C7.38349 6.30962 7.5796 5.92417 7.83149 5.57592C8.08508 5.22766 8.39107 4.92167 8.73932 4.66809C9.08758 4.4162 9.47302 4.22009 9.88214 4.08654C10.2913 3.95467 10.719 3.88705 11.1501 3.88874C11.4358 3.88705 11.7232 3.91579 12.0038 3.97496C12.2844 4.03413 12.5583 4.12204 12.8203 4.23869C13.0824 4.35703 13.3309 4.50072 13.5625 4.66978C13.7941 4.84053 14.0071 5.03325 14.1964 5.24795C14.6174 5.15835 15.0502 5.13637 15.4779 5.18033C15.9056 5.22428 16.3232 5.33755 16.7171 5.51168C17.1093 5.6875 17.4727 5.92248 17.7923 6.21157C18.1118 6.49896 18.384 6.83538 18.5987 7.209C18.7423 7.45582 18.8607 7.71786 18.9503 7.99173C19.0399 8.26391 19.1007 8.54454 19.1295 8.83024C19.1599 9.11595 19.1599 9.40334 19.1278 9.68905C19.0974 9.97475 19.0348 10.2554 18.9452 10.5276C19.2343 10.8471 19.4693 11.2089 19.6451 11.6028ZM14.0122 18.8197C14.3807 18.6676 14.7154 18.4428 14.9978 18.1604C15.2801 17.8781 15.5049 17.5434 15.6571 17.1731C15.8092 16.8046 15.8887 16.409 15.8887 16.01V12.2401C15.8876 12.2367 15.8864 12.2328 15.8853 12.2283C15.8842 12.2249 15.8825 12.2215 15.8802 12.2181C15.878 12.2147 15.8752 12.2119 15.8718 12.2097C15.8684 12.2063 15.865 12.204 15.8616 12.2029L14.4974 11.4151V15.9695C14.4974 16.0151 14.4906 16.0624 14.4788 16.1064C14.4669 16.152 14.45 16.1943 14.4264 16.2349C14.4027 16.2755 14.3756 16.3126 14.3418 16.3448C14.309 16.3775 14.272 16.4059 14.2319 16.4293L11.0013 18.294C10.9742 18.3109 10.9286 18.3346 10.9049 18.3481C11.0385 18.4613 11.1839 18.5611 11.336 18.649C11.4899 18.7369 11.6488 18.8113 11.8144 18.8722C11.9801 18.9313 12.1509 18.977 12.3233 19.0074C12.4974 19.0378 12.6732 19.053 12.8491 19.053C13.248 19.053 13.6436 18.9736 14.0122 18.8197ZM6.31844 16.2602C6.51962 16.6068 6.78504 16.9077 7.10117 17.1512C7.419 17.3946 7.77908 17.5721 8.16453 17.6752C8.54998 17.7784 8.95233 17.8054 9.34792 17.753C9.74351 17.7006 10.1239 17.5721 10.4705 17.3726L13.7366 15.4877L13.7451 15.4792C13.7473 15.477 13.749 15.4736 13.7501 15.4691C13.7524 15.4657 13.7541 15.4623 13.7552 15.4589V13.8698L9.81283 16.1504C9.77225 16.174 9.72999 16.1909 9.68603 16.2045C9.64039 16.2163 9.59474 16.2214 9.54741 16.2214C9.50176 16.2214 9.45612 16.2163 9.41047 16.2045C9.36652 16.1909 9.32256 16.174 9.28199 16.1504L6.05133 14.284C6.0226 14.2671 5.98033 14.2417 5.95666 14.2265C5.92623 14.4006 5.91102 14.5764 5.91102 14.7523C5.91102 14.9281 5.92792 15.1039 5.95835 15.278C5.98878 15.4505 6.03612 15.6212 6.09529 15.7869C6.15615 15.9526 6.23053 16.1115 6.31844 16.2636V16.2602ZM5.46978 9.21062C5.2703 9.55718 5.14182 9.93925 5.08941 10.3348C5.037 10.7304 5.06405 11.1311 5.16717 11.5182C5.2703 11.9037 5.44781 12.2638 5.69125 12.5816C5.93469 12.8977 6.2373 13.1631 6.58217 13.3626L9.84664 15.2493C9.85002 15.2504 9.85396 15.2515 9.85847 15.2527H9.8703C9.87481 15.2527 9.87876 15.2515 9.88214 15.2493C9.88552 15.2482 9.8889 15.2465 9.89228 15.2442L11.2616 14.453L7.31925 12.1775C7.28037 12.1539 7.24318 12.1251 7.20937 12.093C7.17661 12.0602 7.1482 12.0232 7.12484 11.9831C7.10286 11.9426 7.08427 11.9003 7.07243 11.8547C7.0606 11.8107 7.05384 11.7651 7.05553 11.7177V7.87846C6.88985 7.93932 6.72925 8.0137 6.5771 8.10161C6.42495 8.19121 6.28125 8.29265 6.14601 8.40591C6.01245 8.51918 5.88735 8.64428 5.77408 8.77953C5.66082 8.91308 5.56107 9.05847 5.47316 9.21062H5.46978ZM16.6832 11.8208C16.7238 11.8445 16.761 11.8716 16.7948 11.9054C16.8269 11.9375 16.8557 11.9747 16.8794 12.0153C16.9013 12.0558 16.9199 12.0998 16.9318 12.1437C16.9419 12.1894 16.9487 12.235 16.947 12.2824V16.1216C17.4896 15.9221 17.963 15.5722 18.3129 15.1124C18.6646 14.6525 18.8759 14.1031 18.9249 13.5283C18.974 12.9535 18.859 12.3753 18.5919 11.8631C18.3248 11.3509 17.9174 10.9248 17.417 10.6374L14.1525 8.75079C14.1491 8.74966 14.1452 8.74853 14.1407 8.74741H14.1288C14.1254 8.74853 14.1215 8.74966 14.117 8.75079C14.1136 8.75191 14.1102 8.7536 14.1068 8.75586L12.7443 9.54366L16.6866 11.8208H16.6832ZM18.0441 9.77526H18.0425V9.77695L18.0441 9.77526ZM18.0425 9.77357C18.1405 9.20555 18.0746 8.62061 17.8514 8.08809C17.63 7.55556 17.2597 7.09742 16.7864 6.76607C16.313 6.43641 15.7551 6.24707 15.1787 6.22171C14.6005 6.19804 14.0291 6.33836 13.5287 6.62575L10.2642 8.51073C10.2608 8.51298 10.258 8.5158 10.2558 8.51918L10.249 8.52932C10.2479 8.5327 10.2467 8.53665 10.2456 8.54116C10.2445 8.54454 10.2439 8.54848 10.2439 8.55299V10.1286L14.1863 7.85141C14.2269 7.82774 14.2708 7.81084 14.3148 7.79731C14.3604 7.78548 14.4061 7.78041 14.4517 7.78041C14.499 7.78041 14.5447 7.78548 14.5903 7.79731C14.6343 7.81084 14.6766 7.82774 14.7171 7.85141L17.9478 9.71778C17.9765 9.73469 18.0188 9.75836 18.0425 9.77357ZM9.50007 8.02892C9.50007 7.98327 9.50683 7.93763 9.51867 7.89198C9.5305 7.84803 9.54741 7.80407 9.57108 7.7635C9.59474 7.72462 9.62179 7.68743 9.6556 7.65361C9.68772 7.62149 9.72492 7.59275 9.76549 7.57078L12.9961 5.70609C13.0266 5.6875 13.0688 5.66383 13.0925 5.65199C12.6496 5.28176 12.1086 5.04508 11.5355 4.97239C10.9624 4.89801 10.3809 4.9893 9.85847 5.23443C9.3344 5.47956 8.89147 5.87008 8.5821 6.35696C8.27273 6.84553 8.10874 7.41017 8.10874 7.98834V11.7583C8.10987 11.7628 8.111 11.7667 8.11212 11.7701C8.11325 11.7735 8.11494 11.7769 8.1172 11.7803C8.11945 11.7836 8.12227 11.787 8.12565 11.7904C8.1279 11.7927 8.13128 11.7949 8.13579 11.7972L9.50007 12.585V8.02892ZM10.2405 13.011L11.997 14.0253L13.7535 13.011V10.984L11.9987 9.96968L10.2422 10.984L10.2405 13.011Z",
"fill": "white"
},
"children": []
},
{
"type": "element",
"name": "rect",
"attributes": {
"x": "0.5",
"y": "0.5",
"width": "23",
"height": "23",
"rx": "5.5",
"stroke": "black",
"stroke-opacity": "0.05"
},
"children": []
}
]
},
"name": "Gpt3"
}
\ No newline at end of file
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import * as React from 'react'
import data from './Gpt3.json'
import IconBase from '@/app/components/base/icons/IconBase'
import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
props,
ref,
) => <IconBase {...props} ref={ref} data={data as IconData} />)
export default Icon
{
"icon": {
"type": "element",
"isRootNode": true,
"name": "svg",
"attributes": {
"width": "24",
"height": "24",
"viewBox": "0 0 24 24",
"fill": "none",
"xmlns": "http://www.w3.org/2000/svg"
},
"children": [
{
"type": "element",
"name": "rect",
"attributes": {
"width": "24",
"height": "24",
"rx": "6",
"fill": "#AB68FF"
},
"children": []
},
{
"type": "element",
"name": "path",
"attributes": {
"d": "M19.6451 11.6028C19.8209 11.995 19.9325 12.4142 19.9781 12.8419C20.0221 13.2696 20.0001 13.7024 19.9088 14.1234C19.8192 14.5443 19.6637 14.9484 19.4473 15.3203C19.3053 15.5688 19.1379 15.8021 18.9452 16.0168C18.7542 16.2298 18.5412 16.4225 18.3096 16.5916C18.0763 16.7606 17.8278 16.9027 17.564 17.0193C17.302 17.1343 17.0281 17.2222 16.7475 17.2796C16.6156 17.6888 16.4195 18.0759 16.1659 18.4242C15.914 18.7724 15.6081 19.0784 15.2598 19.3303C14.9115 19.5839 14.5261 19.78 14.117 19.9118C13.7079 20.0454 13.2802 20.1113 12.8491 20.1113C12.5634 20.113 12.276 20.0826 11.9953 20.0251C11.7164 19.9659 11.4425 19.8763 11.1805 19.7597C10.9184 19.643 10.6699 19.4977 10.4383 19.3286C10.2084 19.1595 9.99541 18.9651 9.80606 18.7504C9.38342 18.8417 8.95064 18.8637 8.52293 18.8197C8.09522 18.7741 7.67596 18.6625 7.28206 18.4867C6.88985 18.3126 6.52638 18.0759 6.20687 17.7868C5.88735 17.4977 5.61517 17.1596 5.40047 16.7877C5.25677 16.5392 5.13843 16.2771 5.04883 16.005C4.95924 15.7328 4.90007 15.4522 4.86964 15.1665C4.83921 14.8824 4.8409 14.595 4.87133 14.3093C4.90176 14.0253 4.96431 13.7447 5.05391 13.4725C4.76651 13.153 4.52983 12.7895 4.35402 12.3973C4.17989 12.0034 4.06662 11.5859 4.02267 11.1581C3.97702 10.7304 4.00069 10.2976 4.09029 9.8767C4.17989 9.45575 4.33542 9.05171 4.55181 8.67978C4.69382 8.43127 4.86118 8.19628 5.05222 7.98327C5.24325 7.77026 5.45795 7.57754 5.68956 7.40848C5.92116 7.23943 6.17136 7.09573 6.4334 6.98077C6.69713 6.86412 6.971 6.77791 7.25163 6.72043C7.38349 6.30962 7.5796 5.92417 7.83149 5.57592C8.08508 5.22766 8.39107 4.92167 8.73932 4.66809C9.08758 4.4162 9.47302 4.22009 9.88214 4.08654C10.2913 3.95467 10.719 3.88705 11.1501 3.88874C11.4358 3.88705 11.7232 3.91579 12.0038 3.97496C12.2844 4.03413 12.5583 4.12204 12.8203 4.23869C13.0824 4.35703 13.3309 4.50072 13.5625 4.66978C13.7941 4.84053 14.0071 5.03325 14.1964 5.24795C14.6174 5.15835 15.0502 5.13637 15.4779 5.18033C15.9056 5.22428 16.3232 5.33755 16.7171 5.51168C17.1093 5.6875 17.4727 5.92248 17.7923 6.21157C18.1118 6.49896 18.384 6.83538 18.5987 7.209C18.7423 7.45582 18.8607 7.71786 18.9503 7.99173C19.0399 8.26391 19.1007 8.54454 19.1295 8.83024C19.1599 9.11595 19.1599 9.40334 19.1278 9.68905C19.0974 9.97475 19.0348 10.2554 18.9452 10.5276C19.2343 10.8471 19.4693 11.2089 19.6451 11.6028ZM14.0122 18.8197C14.3807 18.6676 14.7154 18.4428 14.9978 18.1604C15.2801 17.8781 15.5049 17.5434 15.6571 17.1731C15.8092 16.8046 15.8887 16.409 15.8887 16.01V12.2401C15.8876 12.2367 15.8864 12.2328 15.8853 12.2283C15.8842 12.2249 15.8825 12.2215 15.8802 12.2181C15.878 12.2147 15.8752 12.2119 15.8718 12.2097C15.8684 12.2063 15.865 12.204 15.8616 12.2029L14.4974 11.4151V15.9695C14.4974 16.0151 14.4906 16.0624 14.4788 16.1064C14.4669 16.152 14.45 16.1943 14.4264 16.2349C14.4027 16.2755 14.3756 16.3126 14.3418 16.3448C14.309 16.3775 14.272 16.4059 14.2319 16.4293L11.0013 18.294C10.9742 18.3109 10.9286 18.3346 10.9049 18.3481C11.0385 18.4613 11.1839 18.5611 11.336 18.649C11.4899 18.7369 11.6488 18.8113 11.8144 18.8722C11.9801 18.9313 12.1509 18.977 12.3233 19.0074C12.4974 19.0378 12.6732 19.053 12.8491 19.053C13.248 19.053 13.6436 18.9736 14.0122 18.8197ZM6.31844 16.2602C6.51962 16.6068 6.78504 16.9077 7.10117 17.1512C7.419 17.3946 7.77908 17.5721 8.16453 17.6752C8.54998 17.7784 8.95233 17.8054 9.34792 17.753C9.74351 17.7006 10.1239 17.5721 10.4705 17.3726L13.7366 15.4877L13.7451 15.4792C13.7473 15.477 13.749 15.4736 13.7501 15.4691C13.7524 15.4657 13.7541 15.4623 13.7552 15.4589V13.8698L9.81283 16.1504C9.77225 16.174 9.72999 16.1909 9.68603 16.2045C9.64039 16.2163 9.59474 16.2214 9.54741 16.2214C9.50176 16.2214 9.45612 16.2163 9.41047 16.2045C9.36652 16.1909 9.32256 16.174 9.28199 16.1504L6.05133 14.284C6.0226 14.2671 5.98033 14.2417 5.95666 14.2265C5.92623 14.4006 5.91102 14.5764 5.91102 14.7523C5.91102 14.9281 5.92792 15.1039 5.95835 15.278C5.98878 15.4505 6.03612 15.6212 6.09529 15.7869C6.15615 15.9526 6.23053 16.1115 6.31844 16.2636V16.2602ZM5.46978 9.21062C5.2703 9.55718 5.14182 9.93925 5.08941 10.3348C5.037 10.7304 5.06405 11.1311 5.16717 11.5182C5.2703 11.9037 5.44781 12.2638 5.69125 12.5816C5.93469 12.8977 6.2373 13.1631 6.58217 13.3626L9.84664 15.2493C9.85002 15.2504 9.85396 15.2515 9.85847 15.2527H9.8703C9.87481 15.2527 9.87876 15.2515 9.88214 15.2493C9.88552 15.2482 9.8889 15.2465 9.89228 15.2442L11.2616 14.453L7.31925 12.1775C7.28037 12.1539 7.24318 12.1251 7.20937 12.093C7.17661 12.0602 7.1482 12.0232 7.12484 11.9831C7.10286 11.9426 7.08427 11.9003 7.07243 11.8547C7.0606 11.8107 7.05384 11.7651 7.05553 11.7177V7.87846C6.88985 7.93932 6.72925 8.0137 6.5771 8.10161C6.42495 8.19121 6.28125 8.29265 6.14601 8.40591C6.01245 8.51918 5.88735 8.64428 5.77408 8.77953C5.66082 8.91308 5.56107 9.05847 5.47316 9.21062H5.46978ZM16.6832 11.8208C16.7238 11.8445 16.761 11.8716 16.7948 11.9054C16.8269 11.9375 16.8557 11.9747 16.8794 12.0153C16.9013 12.0558 16.9199 12.0998 16.9318 12.1437C16.9419 12.1894 16.9487 12.235 16.947 12.2824V16.1216C17.4896 15.9221 17.963 15.5722 18.3129 15.1124C18.6646 14.6525 18.8759 14.1031 18.9249 13.5283C18.974 12.9535 18.859 12.3753 18.5919 11.8631C18.3248 11.3509 17.9174 10.9248 17.417 10.6374L14.1525 8.75079C14.1491 8.74966 14.1452 8.74853 14.1407 8.74741H14.1288C14.1254 8.74853 14.1215 8.74966 14.117 8.75079C14.1136 8.75191 14.1102 8.7536 14.1068 8.75586L12.7443 9.54366L16.6866 11.8208H16.6832ZM18.0441 9.77526H18.0425V9.77695L18.0441 9.77526ZM18.0425 9.77357C18.1405 9.20555 18.0746 8.62061 17.8514 8.08809C17.63 7.55556 17.2597 7.09742 16.7864 6.76607C16.313 6.43641 15.7551 6.24707 15.1787 6.22171C14.6005 6.19804 14.0291 6.33836 13.5287 6.62575L10.2642 8.51073C10.2608 8.51298 10.258 8.5158 10.2558 8.51918L10.249 8.52932C10.2479 8.5327 10.2467 8.53665 10.2456 8.54116C10.2445 8.54454 10.2439 8.54848 10.2439 8.55299V10.1286L14.1863 7.85141C14.2269 7.82774 14.2708 7.81084 14.3148 7.79731C14.3604 7.78548 14.4061 7.78041 14.4517 7.78041C14.499 7.78041 14.5447 7.78548 14.5903 7.79731C14.6343 7.81084 14.6766 7.82774 14.7171 7.85141L17.9478 9.71778C17.9765 9.73469 18.0188 9.75836 18.0425 9.77357ZM9.50007 8.02892C9.50007 7.98327 9.50683 7.93763 9.51867 7.89198C9.5305 7.84803 9.54741 7.80407 9.57108 7.7635C9.59474 7.72462 9.62179 7.68743 9.6556 7.65361C9.68772 7.62149 9.72492 7.59275 9.76549 7.57078L12.9961 5.70609C13.0266 5.6875 13.0688 5.66383 13.0925 5.65199C12.6496 5.28176 12.1086 5.04508 11.5355 4.97239C10.9624 4.89801 10.3809 4.9893 9.85847 5.23443C9.3344 5.47956 8.89147 5.87008 8.5821 6.35696C8.27273 6.84553 8.10874 7.41017 8.10874 7.98834V11.7583C8.10987 11.7628 8.111 11.7667 8.11212 11.7701C8.11325 11.7735 8.11494 11.7769 8.1172 11.7803C8.11945 11.7836 8.12227 11.787 8.12565 11.7904C8.1279 11.7927 8.13128 11.7949 8.13579 11.7972L9.50007 12.585V8.02892ZM10.2405 13.011L11.997 14.0253L13.7535 13.011V10.984L11.9987 9.96968L10.2422 10.984L10.2405 13.011Z",
"fill": "white"
},
"children": []
},
{
"type": "element",
"name": "rect",
"attributes": {
"x": "0.5",
"y": "0.5",
"width": "23",
"height": "23",
"rx": "5.5",
"stroke": "black",
"stroke-opacity": "0.05"
},
"children": []
}
]
},
"name": "Gpt4"
}
\ No newline at end of file
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import * as React from 'react'
import data from './Gpt4.json'
import IconBase from '@/app/components/base/icons/IconBase'
import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
props,
ref,
) => <IconBase {...props} ref={ref} data={data as IconData} />)
export default Icon
export { default as Anthropic } from './Anthropic'
export { default as Gpt3 } from './Gpt3'
export { default as Gpt4 } from './Gpt4'
{
"icon": {
"type": "element",
"isRootNode": true,
"name": "svg",
"attributes": {
"width": "16",
"height": "16",
"viewBox": "0 0 16 16",
"fill": "none",
"xmlns": "http://www.w3.org/2000/svg"
},
"children": [
{
"type": "element",
"name": "path",
"attributes": {
"d": "M13.3332 4L5.99984 11.3333L2.6665 8",
"stroke": "#155EEF",
"stroke-width": "2",
"stroke-linecap": "round",
"stroke-linejoin": "round"
},
"children": []
}
]
},
"name": "Checked"
}
\ No newline at end of file
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import * as React from 'react'
import data from './Checked.json'
import IconBase from '@/app/components/base/icons/IconBase'
import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
props,
ref,
) => <IconBase {...props} ref={ref} data={data as IconData} />)
export default Icon
export { default as Checked } from './Checked'
{
"icon": {
"type": "element",
"isRootNode": true,
"name": "svg",
"attributes": {
"width": "24",
"height": "24",
"viewBox": "0 0 24 24",
"fill": "none",
"xmlns": "http://www.w3.org/2000/svg"
},
"children": [
{
"type": "element",
"name": "path",
"attributes": {
"d": "M22.501 12.2331C22.501 11.3698 22.4296 10.7398 22.2748 10.0864H12.2153V13.983H18.12C18.001 14.9514 17.3582 16.4097 15.9296 17.3897L15.9096 17.5202L19.0902 19.9349L19.3106 19.9564C21.3343 18.1247 22.501 15.4297 22.501 12.2331Z",
"fill": "#4285F4"
},
"children": []
},
{
"type": "element",
"name": "path",
"attributes": {
"d": "M12.2147 22.5001C15.1075 22.5001 17.5361 21.5667 19.3099 19.9567L15.929 17.39C15.0242 18.0083 13.8099 18.44 12.2147 18.44C9.38142 18.44 6.97669 16.6083 6.11947 14.0767L5.99382 14.0871L2.68656 16.5955L2.64331 16.7133C4.40519 20.1433 8.02423 22.5001 12.2147 22.5001Z",
"fill": "#34A853"
},
"children": []
},
{
"type": "element",
"name": "path",
"attributes": {
"d": "M6.11997 14.0765C5.89379 13.4232 5.76289 12.7231 5.76289 11.9998C5.76289 11.2764 5.89379 10.5765 6.10807 9.92313L6.10208 9.78398L2.75337 7.23535L2.64381 7.28642C1.91765 8.70977 1.50098 10.3081 1.50098 11.9998C1.50098 13.6915 1.91765 15.2897 2.64381 16.7131L6.11997 14.0765Z",
"fill": "#FBBC05"
},
"children": []
},
{
"type": "element",
"name": "path",
"attributes": {
"d": "M12.2148 5.55997C14.2267 5.55997 15.5838 6.41163 16.3576 7.12335L19.3814 4.23C17.5243 2.53834 15.1076 1.5 12.2148 1.5C8.02426 1.5 4.4052 3.85665 2.64331 7.28662L6.10759 9.92332C6.97672 7.39166 9.38146 5.55997 12.2148 5.55997Z",
"fill": "#EB4335"
},
"children": []
}
]
},
"name": "Google"
}
\ No newline at end of file
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import * as React from 'react'
import data from './Google.json'
import IconBase from '@/app/components/base/icons/IconBase'
import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
props,
ref,
) => <IconBase {...props} ref={ref} data={data as IconData} />)
export default Icon
{
"icon": {
"type": "element",
"isRootNode": true,
"name": "svg",
"attributes": {
"width": "24",
"height": "24",
"viewBox": "0 0 24 24",
"fill": "none",
"xmlns": "http://www.w3.org/2000/svg"
},
"children": [
{
"type": "element",
"name": "path",
"attributes": {
"fill-rule": "evenodd",
"clip-rule": "evenodd",
"d": "M9.59235 3.32566C10.3587 3.11341 11.1661 3 12 3C13.962 3 15.7773 3.62779 17.2561 4.69345C16.4693 5.21349 15.8824 5.77819 15.4756 6.38193C14.854 7.30445 14.6947 8.25844 14.8234 9.12887C14.9484 9.97416 15.3366 10.696 15.7446 11.2301C16.1402 11.7479 16.6256 12.181 17.0531 12.3946C18.1294 12.9327 19.3714 13.2022 20.2999 13.341C21.1399 13.4667 22.9206 13.8871 22.9865 12.5492C22.9955 12.3672 23 12.1841 23 12C23 5.92487 18.0751 1 12 1C5.92487 1 1 5.92487 1 12C1 18.0751 5.92487 23 12 23C12.1841 23 12.3672 22.9955 12.5492 22.9865C13.1008 22.9593 13.526 22.4902 13.4988 21.9385C13.4716 21.3869 13.0024 20.9618 12.4508 20.9889C12.3015 20.9963 12.1512 21 12 21C8.49063 21 5.45038 18.9914 3.96619 16.0611L4.93474 15.502L8.50745 16.1706C9.43309 16.3439 10.2876 15.6313 10.2834 14.6896L10.2694 11.5365L12.0952 8.41051C12.3911 7.90404 12.3646 7.27161 12.0274 6.79167L9.59235 3.32566Z",
"fill": "#444CE7"
},
"children": []
},
{
"type": "element",
"name": "path",
"attributes": {
"fill-rule": "evenodd",
"clip-rule": "evenodd",
"d": "M13.9456 12.6561C13.5777 12.5165 13.1621 12.6057 12.8839 12.884C12.6056 13.1623 12.5164 13.5778 12.656 13.9458L15.8228 22.2945C15.969 22.68 16.3367 22.9362 16.7489 22.9399C17.1611 22.9435 17.5333 22.6938 17.6863 22.3111L19.007 19.0071L22.311 17.6865C22.6937 17.5334 22.9434 17.1612 22.9397 16.749C22.9361 16.3368 22.6799 15.9691 22.2944 15.8229L13.9456 12.6561Z",
"fill": "#444CE7"
},
"children": []
}
]
},
"name": "WebReader"
}
\ No newline at end of file
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import * as React from 'react'
import data from './WebReader.json'
import IconBase from '@/app/components/base/icons/IconBase'
import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
props,
ref,
) => <IconBase {...props} ref={ref} data={data as IconData} />)
export default Icon
{
"icon": {
"type": "element",
"isRootNode": true,
"name": "svg",
"attributes": {
"width": "24",
"height": "24",
"viewBox": "0 0 24 24",
"fill": "none",
"xmlns": "http://www.w3.org/2000/svg"
},
"children": [
{
"type": "element",
"name": "path",
"attributes": {
"d": "M23.8431 5.0001H19.2179H19.0609V5.15706V5.66001V5.81696H19.2179H19.5393C19.9131 5.81696 20.2502 6.00882 20.4411 6.33021C20.632 6.65161 20.6392 7.0394 20.4603 7.36765L15.3174 16.8077L12.9751 11.2238L15.1813 7.17527C15.6379 6.33743 16.5143 5.81696 17.4684 5.81696H17.5726H17.7296V5.66001V5.15706V5.0001H17.5726H12.9474H12.7905V5.15706V5.66001V5.81696H12.9474H13.2688C13.6426 5.81696 13.9797 6.00882 14.1706 6.33021C14.3615 6.65161 14.3687 7.0394 14.1899 7.36765L12.5896 10.305L11.1634 6.9051C11.0601 6.65867 11.0856 6.38965 11.2336 6.16714C11.3816 5.94462 11.6197 5.81696 11.887 5.81696H12.2526H12.4095V5.66001V5.15706V5.0001H12.2526H6.72092H6.56396V5.15706V5.66001V5.81696H6.72092H6.79699C7.88821 5.81696 8.866 6.46719 9.28817 7.47344L11.3954 12.497L9.04698 16.8077L4.89304 6.9051C4.78966 6.65867 4.81525 6.38965 4.9632 6.16714C5.11116 5.94462 5.34932 5.81696 5.61657 5.81696H6.17832H6.33527V5.66001V5.15706V5.0001H6.17832H0.156957H0V5.15706V5.66001V5.81696H0.156957H0.52654C1.61776 5.81696 2.59561 6.46719 3.01772 7.47344L7.80628 18.889C7.89004 19.0887 8.08425 19.2177 8.30111 19.2177C8.50014 19.2177 8.67588 19.1131 8.77125 18.9381L9.39589 17.7918L11.7807 13.4155L14.0767 18.889C14.1604 19.0886 14.3547 19.2176 14.5715 19.2176C14.7705 19.2176 14.9463 19.1131 15.0417 18.938L15.6663 17.7917L21.4517 7.17517C21.9083 6.33733 22.7847 5.81686 23.7388 5.81686H23.843H24V5.6599V5.15696V5H23.8431V5.0001Z",
"fill": "#222A30"
},
"children": []
}
]
},
"name": "Wikipedia"
}
\ No newline at end of file
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import * as React from 'react'
import data from './Wikipedia.json'
import IconBase from '@/app/components/base/icons/IconBase'
import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
props,
ref,
) => <IconBase {...props} ref={ref} data={data as IconData} />)
export default Icon
export { default as Google } from './Google'
export { default as WebReader } from './WebReader'
export { default as Wikipedia } from './Wikipedia'
{
"icon": {
"type": "element",
"isRootNode": true,
"name": "svg",
"attributes": {
"width": "12",
"height": "12",
"viewBox": "0 0 12 12",
"fill": "none",
"xmlns": "http://www.w3.org/2000/svg"
},
"children": [
{
"type": "element",
"name": "g",
"attributes": {
"clip-path": "url(#clip0_7847_32895)"
},
"children": [
{
"type": "element",
"name": "path",
"attributes": {
"d": "M10.5 2.5C10.5 3.32843 8.48528 4 6 4C3.51472 4 1.5 3.32843 1.5 2.5M10.5 2.5C10.5 1.67157 8.48528 1 6 1C3.51472 1 1.5 1.67157 1.5 2.5M10.5 2.5V9.5C10.5 10.33 8.5 11 6 11C3.5 11 1.5 10.33 1.5 9.5V2.5M10.5 6C10.5 6.83 8.5 7.5 6 7.5C3.5 7.5 1.5 6.83 1.5 6",
"stroke": "#667085",
"stroke-width": "1.25",
"stroke-linecap": "round",
"stroke-linejoin": "round"
},
"children": []
}
]
},
{
"type": "element",
"name": "defs",
"attributes": {},
"children": [
{
"type": "element",
"name": "clipPath",
"attributes": {
"id": "clip0_7847_32895"
},
"children": [
{
"type": "element",
"name": "rect",
"attributes": {
"width": "12",
"height": "12",
"fill": "white"
},
"children": []
}
]
}
]
}
]
},
"name": "DataSet"
}
\ No newline at end of file
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import * as React from 'react'
import data from './DataSet.json'
import IconBase from '@/app/components/base/icons/IconBase'
import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
props,
ref,
) => <IconBase {...props} ref={ref} data={data as IconData} />)
export default Icon
{
"icon": {
"type": "element",
"isRootNode": true,
"name": "svg",
"attributes": {
"width": "12",
"height": "12",
"viewBox": "0 0 12 12",
"fill": "none",
"xmlns": "http://www.w3.org/2000/svg"
},
"children": [
{
"type": "element",
"name": "g",
"attributes": {
"clip-path": "url(#clip0_7998_4025)"
},
"children": [
{
"type": "element",
"name": "path",
"attributes": {
"d": "M6 1.125V2.375M6 9V11M2.875 6H1.125M10.625 6H9.875M9.22855 9.22855L8.875 8.875M9.33211 2.70789L8.625 3.415M2.46079 9.53921L3.875 8.125M2.56434 2.60434L3.625 3.665",
"stroke": "#667085",
"stroke-width": "1.25",
"stroke-linecap": "round",
"stroke-linejoin": "round"
},
"children": []
}
]
},
{
"type": "element",
"name": "defs",
"attributes": {},
"children": [
{
"type": "element",
"name": "clipPath",
"attributes": {
"id": "clip0_7998_4025"
},
"children": [
{
"type": "element",
"name": "rect",
"attributes": {
"width": "12",
"height": "12",
"fill": "white"
},
"children": []
}
]
}
]
}
]
},
"name": "Loading"
}
\ No newline at end of file
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import * as React from 'react'
import data from './Loading.json'
import IconBase from '@/app/components/base/icons/IconBase'
import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
props,
ref,
) => <IconBase {...props} ref={ref} data={data as IconData} />)
export default Icon
{
"icon": {
"type": "element",
"isRootNode": true,
"name": "svg",
"attributes": {
"width": "12",
"height": "12",
"viewBox": "0 0 12 12",
"fill": "none",
"xmlns": "http://www.w3.org/2000/svg"
},
"children": [
{
"type": "element",
"name": "g",
"attributes": {
"clip-path": "url(#clip0_7847_32899)"
},
"children": [
{
"type": "element",
"name": "path",
"attributes": {
"d": "M10.5 10.5L8.75005 8.75M10 5.75C10 8.09721 8.09721 10 5.75 10C3.40279 10 1.5 8.09721 1.5 5.75C1.5 3.40279 3.40279 1.5 5.75 1.5C8.09721 1.5 10 3.40279 10 5.75Z",
"stroke": "#667085",
"stroke-width": "1.25",
"stroke-linecap": "round",
"stroke-linejoin": "round"
},
"children": []
}
]
},
{
"type": "element",
"name": "defs",
"attributes": {},
"children": [
{
"type": "element",
"name": "clipPath",
"attributes": {
"id": "clip0_7847_32899"
},
"children": [
{
"type": "element",
"name": "rect",
"attributes": {
"width": "12",
"height": "12",
"fill": "white"
},
"children": []
}
]
}
]
}
]
},
"name": "Search"
}
\ No newline at end of file
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import * as React from 'react'
import data from './Search.json'
import IconBase from '@/app/components/base/icons/IconBase'
import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
props,
ref,
) => <IconBase {...props} ref={ref} data={data as IconData} />)
export default Icon
{
"icon": {
"type": "element",
"isRootNode": true,
"name": "svg",
"attributes": {
"width": "12",
"height": "12",
"viewBox": "0 0 12 12",
"fill": "none",
"xmlns": "http://www.w3.org/2000/svg"
},
"children": [
{
"type": "element",
"name": "path",
"attributes": {
"fill-rule": "evenodd",
"clip-rule": "evenodd",
"d": "M4 6C4 5.72386 4.22386 5.5 4.5 5.5L10.5 5.5C10.7761 5.5 11 5.72386 11 6C11 6.27614 10.7761 6.5 10.5 6.5L4.5 6.5C4.22386 6.5 4 6.27614 4 6Z",
"fill": "#667085"
},
"children": []
},
{
"type": "element",
"name": "path",
"attributes": {
"fill-rule": "evenodd",
"clip-rule": "evenodd",
"d": "M4 3C4 2.72386 4.22386 2.5 4.5 2.5L10.5 2.5C10.7761 2.5 11 2.72386 11 3C11 3.27614 10.7761 3.5 10.5 3.5L4.5 3.5C4.22386 3.5 4 3.27614 4 3Z",
"fill": "#667085"
},
"children": []
},
{
"type": "element",
"name": "path",
"attributes": {
"fill-rule": "evenodd",
"clip-rule": "evenodd",
"d": "M4 9C4 8.72386 4.22386 8.5 4.5 8.5L10.5 8.5C10.7761 8.5 11 8.72386 11 9C11 9.27614 10.7761 9.5 10.5 9.5L4.5 9.5C4.22386 9.5 4 9.27614 4 9Z",
"fill": "#667085"
},
"children": []
},
{
"type": "element",
"name": "path",
"attributes": {
"fill-rule": "evenodd",
"clip-rule": "evenodd",
"d": "M1 6C1 5.44772 1.44772 5 2 5C2.55228 5 3 5.44772 3 6C3 6.55228 2.55228 7 2 7C1.44772 7 1 6.55228 1 6Z",
"fill": "#667085"
},
"children": []
},
{
"type": "element",
"name": "path",
"attributes": {
"fill-rule": "evenodd",
"clip-rule": "evenodd",
"d": "M1 3C1 2.44772 1.44772 2 2 2C2.55228 2 3 2.44772 3 3C3 3.55228 2.55228 4 2 4C1.44772 4 1 3.55228 1 3Z",
"fill": "#667085"
},
"children": []
},
{
"type": "element",
"name": "path",
"attributes": {
"fill-rule": "evenodd",
"clip-rule": "evenodd",
"d": "M1 9C1 8.44772 1.44772 8 2 8C2.55228 8 3 8.44772 3 9C3 9.55228 2.55228 10 2 10C1.44772 10 1 9.55228 1 9Z",
"fill": "#667085"
},
"children": []
}
]
},
"name": "ThoughtList"
}
\ No newline at end of file
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import * as React from 'react'
import data from './ThoughtList.json'
import IconBase from '@/app/components/base/icons/IconBase'
import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
props,
ref,
) => <IconBase {...props} ref={ref} data={data as IconData} />)
export default Icon
{
"icon": {
"type": "element",
"isRootNode": true,
"name": "svg",
"attributes": {
"width": "12",
"height": "12",
"viewBox": "0 0 12 12",
"fill": "none",
"xmlns": "http://www.w3.org/2000/svg"
},
"children": [
{
"type": "element",
"name": "g",
"attributes": {
"clip-path": "url(#clip0_7847_32887)"
},
"children": [
{
"type": "element",
"name": "path",
"attributes": {
"d": "M4.5 1.75V1M2.53033 2.53033L2 2M2.53033 6.5L2 7.03033M6.5 2.53033L7.03033 2M1.75 4.5H1M7.93224 8.09479L6.68637 10.4085C6.54404 10.6728 6.47287 10.805 6.38725 10.8384C6.31295 10.8674 6.22926 10.8592 6.16199 10.8164C6.08447 10.767 6.04028 10.6235 5.95191 10.3366L4.22259 4.72263C4.1504 4.48825 4.1143 4.37107 4.14335 4.29192C4.16865 4.22298 4.22298 4.16865 4.29192 4.14335C4.37107 4.1143 4.48825 4.1504 4.72262 4.2226L10.3366 5.95192C10.6235 6.0403 10.767 6.08449 10.8164 6.16201C10.8592 6.22928 10.8674 6.31297 10.8384 6.38727C10.805 6.47289 10.6728 6.54406 10.4085 6.68639L8.09479 7.93224C8.05551 7.95339 8.03587 7.96396 8.01868 7.97755C8.00341 7.98961 7.98961 8.00341 7.97755 8.01868C7.96396 8.03587 7.95339 8.05551 7.93224 8.09479Z",
"stroke": "#667085",
"stroke-width": "1.25",
"stroke-linecap": "round",
"stroke-linejoin": "round"
},
"children": []
}
]
},
{
"type": "element",
"name": "defs",
"attributes": {},
"children": [
{
"type": "element",
"name": "clipPath",
"attributes": {
"id": "clip0_7847_32887"
},
"children": [
{
"type": "element",
"name": "rect",
"attributes": {
"width": "12",
"height": "12",
"fill": "white"
},
"children": []
}
]
}
]
}
]
},
"name": "WebReader"
}
\ No newline at end of file
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import * as React from 'react'
import data from './WebReader.json'
import IconBase from '@/app/components/base/icons/IconBase'
import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
props,
ref,
) => <IconBase {...props} ref={ref} data={data as IconData} />)
export default Icon
export { default as DataSet } from './DataSet'
export { default as Loading } from './Loading'
export { default as Search } from './Search'
export { default as ThoughtList } from './ThoughtList'
export { default as WebReader } from './WebReader'
{
"icon": {
"type": "element",
"isRootNode": true,
"name": "svg",
"attributes": {
"width": "12",
"height": "12",
"viewBox": "0 0 12 12",
"fill": "none",
"xmlns": "http://www.w3.org/2000/svg"
},
"children": [
{
"type": "element",
"name": "g",
"attributes": {
"id": "link-external-02"
},
"children": [
{
"type": "element",
"name": "path",
"attributes": {
"id": "Icon",
"d": "M10.5 4.5L10.5 1.5M10.5 1.5H7.49999M10.5 1.5L6 6M5 1.5H3.9C3.05992 1.5 2.63988 1.5 2.31901 1.66349C2.03677 1.8073 1.8073 2.03677 1.66349 2.31901C1.5 2.63988 1.5 3.05992 1.5 3.9V8.1C1.5 8.94008 1.5 9.36012 1.66349 9.68099C1.8073 9.96323 2.03677 10.1927 2.31901 10.3365C2.63988 10.5 3.05992 10.5 3.9 10.5H8.1C8.94008 10.5 9.36012 10.5 9.68099 10.3365C9.96323 10.1927 10.1927 9.96323 10.3365 9.68099C10.5 9.36012 10.5 8.94008 10.5 8.1V7",
"stroke": "currentColor",
"stroke-linecap": "round",
"stroke-linejoin": "round"
},
"children": []
}
]
}
]
},
"name": "LinkExternal02"
}
\ No newline at end of file
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import * as React from 'react'
import data from './LinkExternal02.json'
import IconBase from '@/app/components/base/icons/IconBase'
import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
props,
ref,
) => <IconBase {...props} ref={ref} data={data as IconData} />)
export default Icon
export { default as Check } from './Check' export { default as Check } from './Check'
export { default as LinkExternal02 } from './LinkExternal02'
export { default as Loading02 } from './Loading02' export { default as Loading02 } from './Loading02'
export { default as LogOut01 } from './LogOut01' export { default as LogOut01 } from './LogOut01'
export { default as Trash03 } from './Trash03' export { default as Trash03 } from './Trash03'
......
{
"icon": {
"type": "element",
"isRootNode": true,
"name": "svg",
"attributes": {
"width": "16",
"height": "16",
"viewBox": "0 0 16 16",
"fill": "none",
"xmlns": "http://www.w3.org/2000/svg"
},
"children": [
{
"type": "element",
"name": "g",
"attributes": {
"id": "alert-circle"
},
"children": [
{
"type": "element",
"name": "path",
"attributes": {
"id": "Solid",
"fill-rule": "evenodd",
"clip-rule": "evenodd",
"d": "M8 0.666626C3.94992 0.666626 0.666672 3.94987 0.666672 7.99996C0.666672 12.05 3.94992 15.3333 8 15.3333C12.0501 15.3333 15.3333 12.05 15.3333 7.99996C15.3333 3.94987 12.0501 0.666626 8 0.666626ZM8.66667 5.33329C8.66667 4.9651 8.36819 4.66663 8 4.66663C7.63181 4.66663 7.33334 4.9651 7.33334 5.33329V7.99996C7.33334 8.36815 7.63181 8.66663 8 8.66663C8.36819 8.66663 8.66667 8.36815 8.66667 7.99996V5.33329ZM8 9.99996C7.63181 9.99996 7.33334 10.2984 7.33334 10.6666C7.33334 11.0348 7.63181 11.3333 8 11.3333H8.00667C8.37486 11.3333 8.67334 11.0348 8.67334 10.6666C8.67334 10.2984 8.37486 9.99996 8.00667 9.99996H8Z",
"fill": "currentColor"
},
"children": []
}
]
}
]
},
"name": "AlertCircle"
}
\ No newline at end of file
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import * as React from 'react'
import data from './AlertCircle.json'
import IconBase from '@/app/components/base/icons/IconBase'
import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
props,
ref,
) => <IconBase {...props} ref={ref} data={data as IconData} />)
export default Icon
export { default as AlertCircle } from './AlertCircle'
export { default as AlertTriangle } from './AlertTriangle' export { default as AlertTriangle } from './AlertTriangle'
{
"icon": {
"type": "element",
"isRootNode": true,
"name": "svg",
"attributes": {
"width": "16",
"height": "16",
"viewBox": "0 0 16 16",
"fill": "none",
"xmlns": "http://www.w3.org/2000/svg"
},
"children": [
{
"type": "element",
"name": "g",
"attributes": {
"id": "check-circle"
},
"children": [
{
"type": "element",
"name": "path",
"attributes": {
"id": "Solid",
"fill-rule": "evenodd",
"clip-rule": "evenodd",
"d": "M8 0.666626C3.94992 0.666626 0.666672 3.94987 0.666672 7.99996C0.666672 12.05 3.94992 15.3333 8 15.3333C12.0501 15.3333 15.3333 12.05 15.3333 7.99996C15.3333 3.94987 12.0501 0.666626 8 0.666626ZM11.4714 6.47136C11.7318 6.21101 11.7318 5.7889 11.4714 5.52855C11.2111 5.26821 10.7889 5.26821 10.5286 5.52855L7 9.05715L5.47141 7.52855C5.21106 7.2682 4.78895 7.2682 4.5286 7.52855C4.26825 7.7889 4.26825 8.21101 4.5286 8.47136L6.5286 10.4714C6.78895 10.7317 7.21106 10.7317 7.47141 10.4714L11.4714 6.47136Z",
"fill": "currentColor"
},
"children": []
}
]
}
]
},
"name": "CheckCircle"
}
\ No newline at end of file
// GENERATE BY script
// DON NOT EDIT IT MANUALLY
import * as React from 'react'
import data from './CheckCircle.json'
import IconBase from '@/app/components/base/icons/IconBase'
import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
props,
ref,
) => <IconBase {...props} ref={ref} data={data as IconData} />)
export default Icon
export { default as CheckCircle } from './CheckCircle'
export { default as Download02 } from './Download02' export { default as Download02 } from './Download02'
export { default as XCircle } from './XCircle' export { default as XCircle } from './XCircle'
import ReactMarkdown from "react-markdown"; import ReactMarkdown from 'react-markdown'
import "katex/dist/katex.min.css"; import 'katex/dist/katex.min.css'
import RemarkMath from "remark-math"; import RemarkMath from 'remark-math'
import RemarkBreaks from "remark-breaks"; import RemarkBreaks from 'remark-breaks'
import RehypeKatex from "rehype-katex"; import RehypeKatex from 'rehype-katex'
import RemarkGfm from "remark-gfm"; import RemarkGfm from 'remark-gfm'
import SyntaxHighlighter from 'react-syntax-highlighter' import SyntaxHighlighter from 'react-syntax-highlighter'
import { atelierHeathLight } from 'react-syntax-highlighter/dist/esm/styles/hljs' import { atelierHeathLight } from 'react-syntax-highlighter/dist/esm/styles/hljs'
import { useRef, useState, RefObject, useEffect } from "react"; import type { RefObject } from 'react'
import { useEffect, useRef, useState } from 'react'
// import { copyToClipboard } from "../utils"; // import { copyToClipboard } from "../utils";
// https://txtfiddle.com/~hlshwya/extract-urls-from-text
// const urlRegex = /\b((https?|ftp|file):\/\/|(www|ftp)\.)[-A-Z0-9+&@#\/%?=~_|$!:,.;]*[A-Z0-9+&@#\/%=~_|$]/ig
// function highlightURL(content: string) {
// return content.replace(urlRegex, (url) => {
// // fix http:// in [] will be parsed to link agin
// const res = `[${url.replace('://', ':&#47;&#47;')}](${url})`
// return res
// })
// }
export function PreCode(props: { children: any }) { export function PreCode(props: { children: any }) {
const ref = useRef<HTMLPreElement>(null); const ref = useRef<HTMLPreElement>(null)
return ( return (
<pre ref={ref}> <pre ref={ref}>
...@@ -18,38 +28,37 @@ export function PreCode(props: { children: any }) { ...@@ -18,38 +28,37 @@ export function PreCode(props: { children: any }) {
className="copy-code-button" className="copy-code-button"
onClick={() => { onClick={() => {
if (ref.current) { if (ref.current) {
const code = ref.current.innerText; const code = ref.current.innerText
// copyToClipboard(code); // copyToClipboard(code);
} }
}} }}
></span> ></span>
{props.children} {props.children}
</pre> </pre>
); )
} }
const useLazyLoad = (ref: RefObject<Element>): boolean => { const useLazyLoad = (ref: RefObject<Element>): boolean => {
const [isIntersecting, setIntersecting] = useState<boolean>(false); const [isIntersecting, setIntersecting] = useState<boolean>(false)
useEffect(() => { useEffect(() => {
const observer = new IntersectionObserver(([entry]) => { const observer = new IntersectionObserver(([entry]) => {
if (entry.isIntersecting) { if (entry.isIntersecting) {
setIntersecting(true); setIntersecting(true)
observer.disconnect(); observer.disconnect()
} }
}); })
if (ref.current) { if (ref.current)
observer.observe(ref.current); observer.observe(ref.current)
}
return () => { return () => {
observer.disconnect(); observer.disconnect()
}; }
}, [ref]); }, [ref])
return isIntersecting; return isIntersecting
}; }
export function Markdown(props: { content: string }) { export function Markdown(props: { content: string }) {
return ( return (
...@@ -62,26 +71,29 @@ export function Markdown(props: { content: string }) { ...@@ -62,26 +71,29 @@ export function Markdown(props: { content: string }) {
components={{ components={{
code({ node, inline, className, children, ...props }) { code({ node, inline, className, children, ...props }) {
const match = /language-(\w+)/.exec(className || '') const match = /language-(\w+)/.exec(className || '')
return !inline && match ? ( return (!inline && match)
<SyntaxHighlighter ? (
{...props} <SyntaxHighlighter
children={String(children).replace(/\n$/, '')} {...props}
style={atelierHeathLight} children={String(children).replace(/\n$/, '')}
language={match[1]} style={atelierHeathLight}
showLineNumbers language={match[1]}
PreTag="div" showLineNumbers
/> PreTag="div"
) : ( />
<code {...props} className={className}> )
{children} : (
</code> <code {...props} className={className}>
) {children}
} </code>
)
},
}} }}
linkTarget={"_blank"} linkTarget={'_blank'}
> >
{/* Markdown detect has problem. */}
{props.content} {props.content}
</ReactMarkdown> </ReactMarkdown>
</div> </div>
); )
} }
...@@ -9,7 +9,7 @@ import { ...@@ -9,7 +9,7 @@ import {
InformationCircleIcon, InformationCircleIcon,
XCircleIcon, XCircleIcon,
} from '@heroicons/react/20/solid' } from '@heroicons/react/20/solid'
import { createContext } from 'use-context-selector' import { createContext, useContext } from 'use-context-selector'
export type IToastProps = { export type IToastProps = {
type?: 'success' | 'error' | 'warning' | 'info' type?: 'success' | 'error' | 'warning' | 'info'
...@@ -24,6 +24,7 @@ type IToastContext = { ...@@ -24,6 +24,7 @@ type IToastContext = {
const defaultDuring = 3000 const defaultDuring = 3000
export const ToastContext = createContext<IToastContext>({} as IToastContext) export const ToastContext = createContext<IToastContext>({} as IToastContext)
export const useToastContext = () => useContext(ToastContext)
const Toast = ({ const Toast = ({
type = 'info', type = 'info',
duration, duration,
...@@ -31,9 +32,9 @@ const Toast = ({ ...@@ -31,9 +32,9 @@ const Toast = ({
children, children,
}: IToastProps) => { }: IToastProps) => {
// sometimes message is react node array. Not handle it. // sometimes message is react node array. Not handle it.
if (typeof message !== 'string') { if (typeof message !== 'string')
return null return null
}
return <div className={classNames( return <div className={classNames(
'fixed rounded-md p-4 my-4 mx-8 z-50', 'fixed rounded-md p-4 my-4 mx-8 z-50',
'top-0', 'top-0',
......
...@@ -86,7 +86,7 @@ const VoiceInput = ({ ...@@ -86,7 +86,7 @@ const VoiceInput = ({
const formData = new FormData() const formData = new FormData()
formData.append('file', mp3File) formData.append('file', mp3File)
let url = '' let url = '/universal-chat/audio-to-text'
let isPublic = false let isPublic = false
if (params.token) { if (params.token) {
......
'use client'
import type { FC } from 'react'
import React from 'react'
import cn from 'classnames'
import { useTranslation } from 'react-i18next'
import s from './style.module.css'
import Config from '@/app/components/explore/universal-chat/config'
type Props = {
modelId: string
plugins: Record<string, boolean>
dataSets: any[]
}
const ConfigViewPanel: FC<Props> = ({
modelId,
plugins,
dataSets,
}) => {
const { t } = useTranslation()
return (
<div className={cn('absolute top-9 right-0 z-20 p-4 bg-white rounded-2xl shadow-md', s.panelBorder)}>
<div className='w-[368px]'>
<Config
readonly
modelId={modelId}
plugins={plugins}
dataSets={dataSets}
/>
<div className='mt-3 text-xs leading-[18px] text-500 font-normal'>{t('explore.universalChat.viewConfigDetailTip')}</div>
</div>
</div>
)
}
export default React.memo(ConfigViewPanel)
.btn {
background: url(~@/app/components/datasets/documents/assets/action.svg) center center no-repeat transparent;
background-size: 16px 16px;
/* mask-image: ; */
}
.panelBorder {
border: 0.5px solid rgba(0, 0, 0, .05);
}
\ No newline at end of file
'use client'
import type { FC } from 'react'
import React from 'react'
import cn from 'classnames'
import { useBoolean, useClickAway } from 'ahooks'
import s from './style.module.css'
import ModelIcon from '@/app/components/app/configuration/config-model/model-icon'
import { Google, WebReader, Wikipedia } from '@/app/components/base/icons/src/public/plugins'
import ConfigDetail from '@/app/components/explore/universal-chat/config-view/detail'
export type ISummaryProps = {
modelId: string
plugins: Record<string, boolean>
dataSets: any[]
}
const getColorInfo = (modelId: string) => {
if (modelId === 'gpt-4')
return s.gpt4
if (modelId === 'claude-2')
return s.claude
return s.gpt3
}
const getPlugIcon = (pluginId: string) => {
const className = 'w-4 h-4'
switch (pluginId) {
case 'google_search':
return <Google className={className} />
case 'web_reader':
return <WebReader className={className} />
case 'wikipedia':
return <Wikipedia className={className} />
default:
return null
}
}
const Summary: FC<ISummaryProps> = ({
modelId,
plugins,
dataSets,
}) => {
const pluginIds = Object.keys(plugins).filter(key => plugins[key])
const [isShowConfig, { setFalse: hideConfig, toggle: toggleShowConfig }] = useBoolean(false)
const configContentRef = React.useRef(null)
useClickAway(() => {
hideConfig()
}, configContentRef)
return (
<div ref={configContentRef} className='relative'>
<div onClick={toggleShowConfig} className={cn(getColorInfo(modelId), 'flex items-center px-1 h-8 rounded-lg border cursor-pointer')}>
<ModelIcon modelId={modelId} className='!w-6 !h-6' />
<div className='ml-2 text-[13px] font-medium text-gray-900'>{modelId}</div>
{
pluginIds.length > 0 && (
<div className='ml-1.5 flex items-center'>
<div className='mr-1 h-3 w-[1px] bg-[#000] opacity-[0.05]'></div>
<div className='flex space-x-1'>
{pluginIds.map(pluginId => (
<div
key={pluginId}
className={`flex items-center justify-center w-6 h-6 rounded-md ${s.border} bg-white`}
>
{getPlugIcon(pluginId)}</div>
))}
</div>
</div>
)
}
</div>
{isShowConfig && (
<ConfigDetail
modelId={modelId} plugins={plugins} dataSets={dataSets}
/>
)}
</div>
)
}
export default React.memo(Summary)
.border {
border: 1px solid rgba(0, 0, 0, 0.05);
}
.gpt3 {
background: linear-gradient(0deg, #D3F8DF, #D3F8DF),
linear-gradient(0deg, #EDFCF2, #EDFCF2);
border: 1px solid rgba(211, 248, 223, 1)
}
.gpt4 {
background: linear-gradient(0deg, #EBE9FE, #EBE9FE),
linear-gradient(0deg, #F4F3FF, #F4F3FF);
border: 1px solid rgba(235, 233, 254, 1)
}
.claude {
background: linear-gradient(0deg, #F9EBDF, #F9EBDF),
linear-gradient(0deg, #FCF3EB, #FCF3EB);
border: 1px solid rgba(249, 235, 223, 1)
}
\ No newline at end of file
'use client'
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { useBoolean } from 'ahooks'
import { isEqual } from 'lodash-es'
import produce from 'immer'
import FeaturePanel from '@/app/components/app/configuration/base/feature-panel'
import OperationBtn from '@/app/components/app/configuration/base/operation-btn'
import CardItem from '@/app/components/app/configuration/dataset-config/card-item'
import SelectDataSet from '@/app/components/app/configuration/dataset-config/select-dataset'
import type { DataSet } from '@/models/datasets'
type Props = {
readonly?: boolean
dataSets: DataSet[]
onChange?: (data: DataSet[]) => void
}
const DatasetConfig: FC<Props> = ({
readonly,
dataSets,
onChange,
}) => {
const { t } = useTranslation()
const selectedIds = dataSets.map(item => item.id)
const hasData = dataSets.length > 0
const [isShowSelectDataSet, { setTrue: showSelectDataSet, setFalse: hideSelectDataSet }] = useBoolean(false)
const handleSelect = (data: DataSet[]) => {
if (isEqual(data.map(item => item.id), dataSets.map(item => item.id))) {
hideSelectDataSet()
return
}
if (data.find(item => !item.name)) { // has not loaded selected dataset
const newSelected = produce(data, (draft) => {
data.forEach((item, index) => {
if (!item.name) { // not fetched database
const newItem = dataSets.find(i => i.id === item.id)
if (newItem)
draft[index] = newItem
}
})
})
onChange?.(newSelected)
}
else {
onChange?.(data)
}
hideSelectDataSet()
}
const onRemove = (id: string) => {
onChange?.(dataSets.filter(item => item.id !== id))
}
return (
<FeaturePanel
className='mt-3'
title={t('appDebug.feature.dataSet.title')}
headerRight={!readonly && <OperationBtn type="add" onClick={showSelectDataSet} />}
hasHeaderBottomBorder={!hasData}
>
{hasData
? (
<div className='max-h-[220px] overflow-y-auto'>
{dataSets.map(item => (
<CardItem
className="mb-2 !w-full"
key={item.id}
config={item}
onRemove={onRemove}
readonly={readonly}
// TODO: readonly remove btn
/>
))}
</div>
)
: (
<div className='pt-2 pb-1 text-xs text-gray-500'>{t('appDebug.feature.dataSet.noData')}</div>
)}
{isShowSelectDataSet && (
<SelectDataSet
isShow={isShowSelectDataSet}
onClose={hideSelectDataSet}
selectedIds={selectedIds}
onSelect={handleSelect}
/>
)}
</FeaturePanel>
)
}
export default React.memo(DatasetConfig)
'use client'
import type { FC } from 'react'
import React from 'react'
import ModelConfig from './model-config'
import DataConfig from './data-config'
import PluginConfig from './plugins-config'
export type IConfigProps = {
className?: string
readonly?: boolean
modelId: string
onModelChange?: (modelId: string) => void
plugins: Record<string, boolean>
onPluginChange?: (key: string, value: boolean) => void
dataSets: any[]
onDataSetsChange?: (contexts: any[]) => void
}
const Config: FC<IConfigProps> = ({
className,
readonly,
modelId,
onModelChange,
plugins,
onPluginChange,
dataSets,
onDataSetsChange,
}) => {
return (
<div className={className}>
<ModelConfig
readonly={readonly}
modelId={modelId}
onChange={onModelChange}
/>
<PluginConfig
readonly={readonly}
config={plugins}
onChange={onPluginChange}
/>
{(!readonly || (readonly && dataSets.length > 0)) && (
<DataConfig
readonly={readonly}
dataSets={dataSets}
onChange={onDataSetsChange}
/>
)}
</div>
)
}
export default React.memo(Config)
'use client'
import type { FC } from 'react'
import React from 'react'
import cn from 'classnames'
import { useBoolean, useClickAway } from 'ahooks'
import { ChevronDownIcon } from '@heroicons/react/24/outline'
import { useTranslation } from 'react-i18next'
import ModelIcon from '@/app/components/app/configuration/config-model/model-icon'
import { UNIVERSAL_CHAT_MODEL_LIST as MODEL_LIST } from '@/config'
import { Checked as CheckedIcon } from '@/app/components/base/icons/src/public/model'
export type IModelConfigProps = {
modelId: string
onChange?: (model: string) => void
readonly?: boolean
}
const ModelConfig: FC<IModelConfigProps> = ({
modelId,
onChange,
readonly,
}) => {
const { t } = useTranslation()
const currModel = MODEL_LIST.find(item => item.id === modelId)
const [isShowOption, { setFalse: hideOption, toggle: toogleOption }] = useBoolean(false)
const triggerRef = React.useRef(null)
useClickAway(() => {
hideOption()
}, triggerRef)
return (
<div className='flex items-center justify-between h-[52px] px-3 rounded-xl bg-gray-50'>
<div className='text-sm font-semibold text-gray-800'>{t('explore.universalChat.model')}</div>
<div className="relative z-10">
<div
ref={triggerRef}
onClick={() => !readonly && toogleOption()}
className={cn(
readonly ? 'cursor-not-allowed' : 'cursor-pointer', 'flex items-center h-9 px-3 space-x-2 rounded-lg',
isShowOption && 'bg-gray-100',
)}>
<ModelIcon modelId={currModel?.id as string} />
<div className="text-sm gray-900">{currModel?.name}</div>
{!readonly && <ChevronDownIcon className={cn(isShowOption && 'rotate-180', 'w-[14px] h-[14px] text-gray-500')} />}
</div>
{isShowOption && (
<div className={cn('absolute top-10 right-0 bg-white rounded-lg shadow')}>
{MODEL_LIST.map(item => (
<div key={item.id} onClick={() => onChange?.(item.id)} className="w-[232px] flex items-center h-9 px-4 rounded-lg cursor-pointer hover:bg-gray-100">
<ModelIcon className='shrink-0 mr-2' modelId={item?.id} />
<div className="text-sm gray-900 whitespace-nowrap">{item.name}</div>
{(item.id === currModel?.id) && <CheckedIcon className='absolute right-4' />}
</div>
))}
</div>
)}
</div>
</div>
)
}
export default React.memo(ModelConfig)
'use client'
import type { FC } from 'react'
import React, { useEffect } from 'react'
import { useTranslation } from 'react-i18next'
import Item from './item'
import FeaturePanel from '@/app/components/app/configuration/base/feature-panel'
import { Google, WebReader, Wikipedia } from '@/app/components/base/icons/src/public/plugins'
import { getToolProviders } from '@/service/explore'
import Loading from '@/app/components/base/loading'
import AccountSetting from '@/app/components/header/account-setting'
export type IPluginsProps = {
readonly?: boolean
config: Record<string, boolean>
onChange?: (key: string, value: boolean) => void
}
const plugins = [
{ key: 'google_search', icon: <Google /> },
{ key: 'web_reader', icon: <WebReader /> },
{ key: 'wikipedia', icon: <Wikipedia /> },
]
const Plugins: FC<IPluginsProps> = ({
readonly,
config,
onChange,
}) => {
const { t } = useTranslation()
const [isLoading, setIsLoading] = React.useState(!readonly)
const [isSerpApiValid, setIsSerpApiValid] = React.useState(false)
const checkSerpApiKey = async () => {
if (readonly)
return
const provides: any = await getToolProviders()
const isSerpApiValid = !!provides.find((v: any) => v.tool_name === 'serpapi' && v.is_enabled)
setIsSerpApiValid(isSerpApiValid)
setIsLoading(false)
}
useEffect(() => {
checkSerpApiKey()
}, [])
const [showSetSerpAPIKeyModal, setShowSetAPIKeyModal] = React.useState(false)
const itemConfigs = plugins.map((plugin) => {
const res: Record<string, any> = { ...plugin }
const { key } = plugin
res.name = t(`explore.universalChat.plugins.${key}.name`)
if (key === 'web_reader')
res.description = t(`explore.universalChat.plugins.${key}.description`)
if (key === 'google_search' && !isSerpApiValid && !readonly) {
res.readonly = true
res.more = (
<div className='border-t border-[#FEF0C7] flex items-center h-[34px] pl-2 bg-[#FFFAEB] text-gray-700 text-xs '>
<span className='whitespace-pre'>{t('explore.universalChat.plugins.google_search.more.left')}</span>
<span className='cursor-pointer text-[#155EEF]' onClick={() => setShowSetAPIKeyModal(true)}>{t('explore.universalChat.plugins.google_search.more.link')}</span>
<span className='whitespace-pre'>{t('explore.universalChat.plugins.google_search.more.right')}</span>
</div>
)
}
return res
})
const enabledPluginNum = Object.values(config).filter(v => v).length
return (
<>
<FeaturePanel
className='mt-3'
title={
<div className='flex space-x-1'>
<div>{t('explore.universalChat.plugins.name')}</div>
<div className='text-[13px] font-normal text-gray-500'>({enabledPluginNum}/{plugins.length})</div>
</div>}
hasHeaderBottomBorder={false}
>
{isLoading
? (
<div className='flex items-center h-[166px]'>
<Loading type='area' />
</div>
)
: (<div className='space-y-2'>
{itemConfigs.map(item => (
<Item
key={item.key}
icon={item.icon}
name={item.name}
description={item.description}
more={item.more}
enabled={config[item.key]}
onChange={enabled => onChange?.(item.key, enabled)}
readonly={readonly || item.readonly}
/>
))}
</div>)}
</FeaturePanel>
{
showSetSerpAPIKeyModal && (
<AccountSetting activeTab="plugin" onCancel={async () => {
setShowSetAPIKeyModal(false)
await checkSerpApiKey()
}} />
)
}
</>
)
}
export default React.memo(Plugins)
.shadow {
box-shadow: 0px 1px 2px 0px rgba(16, 24, 40, 0.05);
}
\ No newline at end of file
'use client'
import type { FC } from 'react'
import React from 'react'
import cn from 'classnames'
import s from './item.module.css'
import Switch from '@/app/components/base/switch'
export type IItemProps = {
icon: React.ReactNode
name: string
description?: string
more?: React.ReactNode
enabled: boolean
onChange: (enabled: boolean) => void
readonly?: boolean
}
const Item: FC<IItemProps> = ({
icon,
name,
description,
more,
enabled,
onChange,
readonly,
}) => {
return (
<div className={cn('bg-white rounded-xl border border-gray-200 overflow-hidden', s.shadow)}>
<div className='flex justify-between items-center min-h-[48px] px-2'>
<div className='flex items-center space-x-2'>
{icon}
<div className='leading-[18px]'>
<div className='text-[13px] font-medium text-gray-800'>{name}</div>
{description && <div className='text-xs leading-[18px] text-gray-500'>{description}</div>}
</div>
</div>
<Switch size='md' defaultValue={enabled} onChange={onChange} disabled={readonly} />
</div>
{more}
</div>
)
}
export default React.memo(Item)
import { useState } from 'react'
import produce from 'immer'
import { useGetState } from 'ahooks'
import type { ConversationItem } from '@/models/share'
const storageConversationIdKey = 'conversationIdInfo'
type ConversationInfoType = Omit<ConversationItem, 'inputs' | 'id'>
function useConversation() {
const [conversationList, setConversationList] = useState<ConversationItem[]>([])
const [pinnedConversationList, setPinnedConversationList] = useState<ConversationItem[]>([])
const [currConversationId, doSetCurrConversationId, getCurrConversationId] = useGetState<string>('-1')
// when set conversation id, we do not have set appId
const setCurrConversationId = (id: string, appId: string, isSetToLocalStroge = true, newConversationName = '') => {
doSetCurrConversationId(id)
if (isSetToLocalStroge && id !== '-1') {
// conversationIdInfo: {[appId1]: conversationId1, [appId2]: conversationId2}
const conversationIdInfo = globalThis.localStorage?.getItem(storageConversationIdKey) ? JSON.parse(globalThis.localStorage?.getItem(storageConversationIdKey) || '') : {}
conversationIdInfo[appId] = id
globalThis.localStorage?.setItem(storageConversationIdKey, JSON.stringify(conversationIdInfo))
}
}
const getConversationIdFromStorage = (appId: string) => {
const conversationIdInfo = globalThis.localStorage?.getItem(storageConversationIdKey) ? JSON.parse(globalThis.localStorage?.getItem(storageConversationIdKey) || '') : {}
const id = conversationIdInfo[appId]
return id
}
const isNewConversation = currConversationId === '-1'
// input can be updated by user
const [newConversationInputs, setNewConversationInputs] = useState<Record<string, any> | null>(null)
const resetNewConversationInputs = () => {
if (!newConversationInputs)
return
setNewConversationInputs(produce(newConversationInputs, (draft) => {
Object.keys(draft).forEach((key) => {
draft[key] = ''
})
}))
}
const [existConversationInputs, setExistConversationInputs] = useState<Record<string, any> | null>(null)
const currInputs = isNewConversation ? newConversationInputs : existConversationInputs
const setCurrInputs = isNewConversation ? setNewConversationInputs : setExistConversationInputs
// info is muted
const [newConversationInfo, setNewConversationInfo] = useState<ConversationInfoType | null>(null)
const [existConversationInfo, setExistConversationInfo] = useState<ConversationInfoType | null>(null)
const currConversationInfo = isNewConversation ? newConversationInfo : existConversationInfo
return {
conversationList,
setConversationList,
pinnedConversationList,
setPinnedConversationList,
currConversationId,
getCurrConversationId,
setCurrConversationId,
getConversationIdFromStorage,
isNewConversation,
currInputs,
newConversationInputs,
existConversationInputs,
resetNewConversationInputs,
setCurrInputs,
currConversationInfo,
setNewConversationInfo,
setExistConversationInfo,
}
}
export default useConversation
This diff is collapsed.
'use client'
import type { FC } from 'react'
import React from 'react'
import { useTranslation } from 'react-i18next'
import cn from 'classnames'
import type { IConfigProps } from '../config'
import Config from '../config'
import s from './style.module.css'
const Line = (
<svg width="720" height="1" viewBox="0 0 720 1" fill="none" xmlns="http://www.w3.org/2000/svg">
<line y1="0.5" x2="720" y2="0.5" stroke="url(#paint0_linear_6845_53470)"/>
<defs>
<linearGradient id="paint0_linear_6845_53470" x1="0" y1="1" x2="720" y2="1" gradientUnits="userSpaceOnUse">
<stop stopColor="#F2F4F7" stopOpacity="0"/>
<stop offset="0.491667" stopColor="#F2F4F7"/>
<stop offset="1" stopColor="#F2F4F7" stopOpacity="0"/>
</linearGradient>
</defs>
</svg>
)
const Init: FC<IConfigProps> = ({
...configProps
}) => {
const { t } = useTranslation()
return (
<div className='h-full flex items-center'>
<div>
<div className='w-[480px] mx-auto text-center'>
<div className={cn(s.textGradient, 'mb-2 leading-[32px] font-semibold text-[24px]')}>{t('explore.universalChat.welcome')}</div>
<div className='mb-2 font-normal text-sm text-gray-500'>{t('explore.universalChat.welcomeDescribe')}</div>
</div>
<div className='flex mb-2 mx-auto h-8 items-center'>
{Line}
</div>
<Config className='w-[480px] mx-auto' {...configProps} />
</div>
</div>
)
}
export default React.memo(Init)
.textGradient {
background: linear-gradient(to right, rgba(16, 74, 225, 1) 0, rgba(0, 152, 238, 1) 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
text-fill-color: transparent;
}
.installedApp {
height: calc(100vh - 74px);
}
\ No newline at end of file
...@@ -9,11 +9,12 @@ import MembersPage from './members-page' ...@@ -9,11 +9,12 @@ import MembersPage from './members-page'
import IntegrationsPage from './Integrations-page' import IntegrationsPage from './Integrations-page'
import LanguagePage from './language-page' import LanguagePage from './language-page'
import ProviderPage from './provider-page' import ProviderPage from './provider-page'
import PluginPage from './plugin-page'
import DataSourcePage from './data-source-page' import DataSourcePage from './data-source-page'
import s from './index.module.css' import s from './index.module.css'
import Modal from '@/app/components/base/modal' import Modal from '@/app/components/base/modal'
import { Database03 } from '@/app/components/base/icons/src/vender/line/development' import { Database03, PuzzlePiece01 } from '@/app/components/base/icons/src/vender/line/development'
import { Database03 as Database03Solid } from '@/app/components/base/icons/src/vender/solid/development' import { Database03 as Database03Solid, PuzzlePiece01 as PuzzlePiece01Solid } from '@/app/components/base/icons/src/vender/solid/development'
const iconClassName = ` const iconClassName = `
w-4 h-4 ml-3 mr-2 w-4 h-4 ml-3 mr-2
...@@ -80,6 +81,12 @@ export default function AccountSetting({ ...@@ -80,6 +81,12 @@ export default function AccountSetting({
icon: <Database03 className={iconClassName} />, icon: <Database03 className={iconClassName} />,
activeIcon: <Database03Solid className={iconClassName} />, activeIcon: <Database03Solid className={iconClassName} />,
}, },
{
key: 'plugin',
name: t('common.settings.plugin'),
icon: <PuzzlePiece01 className={iconClassName} />,
activeIcon: <PuzzlePiece01Solid className={iconClassName} />,
},
], ],
}, },
] ]
...@@ -148,6 +155,7 @@ export default function AccountSetting({ ...@@ -148,6 +155,7 @@ export default function AccountSetting({
{activeMenu === 'language' && <LanguagePage />} {activeMenu === 'language' && <LanguagePage />}
{activeMenu === 'provider' && <ProviderPage />} {activeMenu === 'provider' && <ProviderPage />}
{activeMenu === 'data-source' && <DataSourcePage />} {activeMenu === 'data-source' && <DataSourcePage />}
{activeMenu === 'plugin' && <PluginPage />}
</div> </div>
</div> </div>
</div> </div>
......
import type { ChangeEvent } from 'react'
import {
ValidatedErrorIcon,
ValidatedErrorMessage,
ValidatedSuccessIcon,
ValidatingTip,
} from './ValidateStatus'
import { ValidatedStatus } from './declarations'
import type { ValidatedStatusState } from './declarations'
type KeyInputProps = {
value?: string
name: string
placeholder: string
className?: string
onChange: (v: string) => void
onFocus?: () => void
validating: boolean
validatedStatusState: ValidatedStatusState
}
const KeyInput = ({
value,
name,
placeholder,
className,
onChange,
onFocus,
validating,
validatedStatusState,
}: KeyInputProps) => {
const handleChange = (e: ChangeEvent<HTMLInputElement>) => {
const inputValue = e.target.value
onChange(inputValue)
}
const getValidatedIcon = () => {
if (validatedStatusState.status === ValidatedStatus.Error || validatedStatusState.status === ValidatedStatus.Exceed)
return <ValidatedErrorIcon />
if (validatedStatusState.status === ValidatedStatus.Success)
return <ValidatedSuccessIcon />
}
const getValidatedTip = () => {
if (validating)
return <ValidatingTip />
if (validatedStatusState.status === ValidatedStatus.Error)
return <ValidatedErrorMessage errorMessage={validatedStatusState.message ?? ''} />
}
return (
<div className={className}>
<div className="mb-2 text-[13px] font-medium text-gray-800">{name}</div>
<div className='
flex items-center px-3 bg-white rounded-lg
shadow-[0_1px_2px_rgba(16,24,40,0.05)]
'>
<input
className='
w-full py-[9px] mr-2
text-xs font-medium text-gray-700 leading-[18px]
appearance-none outline-none bg-transparent
'
value={value}
placeholder={placeholder}
onChange={handleChange}
onFocus={onFocus}
/>
{getValidatedIcon()}
</div>
{getValidatedTip()}
</div>
)
}
export default KeyInput
import { useTranslation } from 'react-i18next'
import Indicator from '../../indicator'
import type { Status } from './declarations'
type OperateProps = {
isOpen: boolean
status: Status
onCancel: () => void
onSave: () => void
onAdd: () => void
onEdit: () => void
}
const Operate = ({
isOpen,
status,
onCancel,
onSave,
onAdd,
onEdit,
}: OperateProps) => {
const { t } = useTranslation()
if (isOpen) {
return (
<div className='flex items-center'>
<div className='
flex items-center
mr-[5px] px-3 h-7 rounded-md cursor-pointer
text-xs font-medium text-gray-700
' onClick={onCancel} >
{t('common.operation.cancel')}
</div>
<div className='
flex items-center
px-3 h-7 rounded-md cursor-pointer bg-primary-700
text-xs font-medium text-white
' onClick={onSave}>
{t('common.operation.save')}
</div>
</div>
)
}
if (status === 'add') {
return (
<div className='
px-3 h-[28px] bg-white border border-gray-200 rounded-md cursor-pointer
text-xs font-medium text-gray-700 flex items-center
' onClick={onAdd}>
{t('common.provider.addKey')}
</div>
)
}
if (status === 'fail' || status === 'success') {
return (
<div className='flex items-center'>
{
status === 'fail' && (
<div className='flex items-center mr-4'>
<div className='text-xs text-[#D92D20]'>{t('common.provider.invalidApiKey')}</div>
<Indicator color='red' className='ml-2' />
</div>
)
}
{
status === 'success' && (
<Indicator color='green' className='mr-4' />
)
}
<div className='
px-3 h-[28px] bg-white border border-gray-200 rounded-md cursor-pointer
text-xs font-medium text-gray-700 flex items-center
' onClick={onEdit}>
{t('common.provider.editKey')}
</div>
</div>
)
}
return null
}
export default Operate
import { useTranslation } from 'react-i18next'
import { AlertCircle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback'
import { CheckCircle } from '@/app/components/base/icons/src/vender/solid/general'
export const ValidatedErrorIcon = () => {
return <AlertCircle className='w-4 h-4 text-[#D92D20]' />
}
export const ValidatedSuccessIcon = () => {
return <CheckCircle className='w-4 h-4 text-[#039855]' />
}
export const ValidatingTip = () => {
const { t } = useTranslation()
return (
<div className={'mt-2 text-primary-600 text-xs font-normal'}>
{t('common.provider.validating')}
</div>
)
}
export const ValidatedErrorMessage = ({ errorMessage }: { errorMessage: string }) => {
const { t } = useTranslation()
return (
<div className={'mt-2 text-[#D92D20] text-xs font-normal'}>
{t('common.provider.validatedError')}{errorMessage}
</div>
)
}
import type { Dispatch, SetStateAction } from 'react'
export enum ValidatedStatus {
Success = 'success',
Error = 'error',
Exceed = 'exceed',
}
export type ValidatedStatusState = {
status?: ValidatedStatus
message?: string
}
export type Status = 'add' | 'fail' | 'success'
export type ValidateValue = Record<string, string | undefined>
export type ValidateCallback = {
before: (v?: ValidateValue) => boolean | undefined
run?: (v?: ValidateValue) => Promise<ValidatedStatusState>
}
export type Form = {
key: string
title: string
placeholder: string
value?: string
validate?: ValidateCallback
handleFocus?: (v: ValidateValue, dispatch: Dispatch<SetStateAction<ValidateValue>>) => void
}
export type KeyFrom = {
text: string
link: string
}
export type KeyValidatorProps = {
type: string
title: React.ReactNode
status: Status
forms: Form[]
keyFrom: KeyFrom
}
import { useState } from 'react'
import { useDebounceFn } from 'ahooks'
import type { DebouncedFunc } from 'lodash-es'
import { ValidatedStatus } from './declarations'
import type { ValidateCallback, ValidateValue, ValidatedStatusState } from './declarations'
export const useValidate: (value: ValidateValue) => [DebouncedFunc<(validateCallback: ValidateCallback) => Promise<void>>, boolean, ValidatedStatusState] = (value) => {
const [validating, setValidating] = useState(false)
const [validatedStatus, setValidatedStatus] = useState<ValidatedStatusState>({})
const { run } = useDebounceFn(async (validateCallback: ValidateCallback) => {
if (!validateCallback.before(value)) {
setValidating(false)
setValidatedStatus({})
return
}
setValidating(true)
if (validateCallback.run) {
const res = await validateCallback?.run(value)
setValidatedStatus(
res.status === 'success'
? { status: ValidatedStatus.Success }
: { status: ValidatedStatus.Error, message: res.message })
setValidating(false)
}
}, { wait: 500 })
return [run, validating, validatedStatus]
}
import { useState } from 'react'
import Operate from './Operate'
import KeyInput from './KeyInput'
import { useValidate } from './hooks'
import type { Form, KeyFrom, Status, ValidateValue } from './declarations'
import { useEventEmitterContextContext } from '@/context/event-emitter'
import { LinkExternal02 } from '@/app/components/base/icons/src/vender/line/general'
export type KeyValidatorProps = {
type: string
title: React.ReactNode
status: Status
forms: Form[]
keyFrom: KeyFrom
onSave: (v: ValidateValue) => Promise<boolean | undefined>
}
const KeyValidator = ({
type,
title,
status,
forms,
keyFrom,
onSave,
}: KeyValidatorProps) => {
const triggerKey = `plugins/${type}`
const { eventEmitter } = useEventEmitterContextContext()
const [isOpen, setIsOpen] = useState(false)
const prevValue = forms.reduce((prev: ValidateValue, next: Form) => {
prev[next.key] = next.value
return prev
}, {})
const [value, setValue] = useState(prevValue)
const [validate, validating, validatedStatusState] = useValidate(value)
eventEmitter?.useSubscription((v) => {
if (v !== triggerKey) {
setIsOpen(false)
setValue(prevValue)
validate({ before: () => false })
}
})
const handleCancel = () => {
eventEmitter?.emit('')
}
const handleSave = async () => {
if (await onSave(value))
eventEmitter?.emit('')
}
const handleAdd = () => {
setIsOpen(true)
eventEmitter?.emit(triggerKey)
}
const handleEdit = () => {
setIsOpen(true)
eventEmitter?.emit(triggerKey)
}
const handleChange = (form: Form, val: string) => {
setValue({ ...value, [form.key]: val })
if (form.validate)
validate(form.validate)
}
const handleFocus = (form: Form) => {
if (form.handleFocus)
form.handleFocus(value, setValue)
}
return (
<div className='mb-2 border-[0.5px] border-gray-200 bg-gray-50 rounded-md'>
<div className={
`flex items-center justify-between px-4 h-[52px] cursor-pointer ${isOpen && 'border-b-[0.5px] border-b-gray-200'}`
}>
{title}
<Operate
isOpen={isOpen}
status={status}
onCancel={handleCancel}
onSave={handleSave}
onAdd={handleAdd}
onEdit={handleEdit}
/>
</div>
{
isOpen && (
<div className='px-4 py-3'>
{
forms.map(form => (
<KeyInput
key={form.key}
className='mb-4'
name={form.title}
placeholder={form.placeholder}
value={value[form.key] || ''}
onChange={v => handleChange(form, v)}
onFocus={() => handleFocus(form)}
validating={validating}
validatedStatusState={validatedStatusState}
/>
))
}
<a className="flex items-center text-xs cursor-pointer text-primary-600" href={keyFrom.link} target={'_blank'}>
{keyFrom.text}
<LinkExternal02 className='w-3 h-3 ml-1 text-primary-600' />
</a>
</div>
)
}
</div>
)
}
export default KeyValidator
import { useTranslation } from 'react-i18next'
import Image from 'next/image'
import SerpapiLogo from '../../assets/serpapi.png'
import KeyValidator from '../key-validator'
import type { Form, ValidateValue } from '../key-validator/declarations'
import { updatePluginKey, validatePluginKey } from './utils'
import { useToastContext } from '@/app/components/base/toast'
import type { PluginProvider } from '@/models/common'
type SerpapiPluginProps = {
plugin: PluginProvider
onUpdate: () => void
}
const SerpapiPlugin = ({
plugin,
onUpdate,
}: SerpapiPluginProps) => {
const { t } = useTranslation()
const { notify } = useToastContext()
const forms: Form[] = [{
key: 'api_key',
title: t('common.plugin.serpapi.apiKey'),
placeholder: t('common.plugin.serpapi.apiKeyPlaceholder'),
value: plugin.credentials?.api_key,
validate: {
before: (v) => {
if (v?.api_key)
return true
},
run: async (v) => {
return validatePluginKey('serpapi', {
credentials: {
api_key: v?.api_key,
},
})
},
},
handleFocus: (v, dispatch) => {
if (v.api_key === plugin.credentials?.api_key)
dispatch({ ...v, api_key: '' })
},
}]
const handleSave = async (v: ValidateValue) => {
if (!v?.api_key || v?.api_key === plugin.credentials?.api_key)
return
const res = await updatePluginKey('serpapi', {
credentials: {
api_key: v?.api_key,
},
})
if (res.status === 'success') {
notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
onUpdate()
return true
}
}
return (
<KeyValidator
type='serpapi'
title={<Image alt='serpapi logo' src={SerpapiLogo} width={64} />}
status={plugin.credentials?.api_key ? 'success' : 'add'}
forms={forms}
keyFrom={{
text: t('common.plugin.serpapi.keyFrom'),
link: 'https://serpapi.com/manage-api-key',
}}
onSave={handleSave}
/>
)
}
export default SerpapiPlugin
import useSWR from 'swr'
import { LockClosedIcon } from '@heroicons/react/24/solid'
import { useTranslation } from 'react-i18next'
import Link from 'next/link'
import SerpapiPlugin from './SerpapiPlugin'
import { fetchPluginProviders } from '@/service/common'
import type { PluginProvider } from '@/models/common'
const PluginPage = () => {
const { t } = useTranslation()
const { data: plugins, mutate } = useSWR('/workspaces/current/tool-providers', fetchPluginProviders)
const Plugin_MAP: Record<string, any> = {
serpapi: (plugin: PluginProvider) => <SerpapiPlugin key='serpapi' plugin={plugin} onUpdate={() => mutate()} />,
}
return (
<div className='pb-7'>
<div>
{plugins?.map(plugin => Plugin_MAP[plugin.tool_name](plugin))}
</div>
<div className='fixed bottom-0 w-[472px] h-[42px] flex items-center bg-white text-xs text-gray-500'>
<LockClosedIcon className='w-3 h-3 mr-1' />
{t('common.provider.encrypted.front')}
<Link
className='text-primary-600 mx-1'
target={'_blank'}
href='https://pycryptodome.readthedocs.io/en/latest/src/cipher/oaep.html'
>
PKCS1_OAEP
</Link>
{t('common.provider.encrypted.back')}
</div>
</div>
)
}
export default PluginPage
import { ValidatedStatus } from '../key-validator/declarations'
import { updatePluginProviderAIKey, validatePluginProviderKey } from '@/service/common'
export const validatePluginKey = async (pluginType: string, body: any) => {
try {
const res = await validatePluginProviderKey({
url: `/workspaces/current/tool-providers/${pluginType}/credentials-validate`,
body,
})
if (res.result === 'success')
return Promise.resolve({ status: ValidatedStatus.Success })
else
return Promise.resolve({ status: ValidatedStatus.Error, message: res.error })
}
catch (e: any) {
return Promise.resolve({ status: ValidatedStatus.Error, message: e.message })
}
}
export const updatePluginKey = async (pluginType: string, body: any) => {
try {
const res = await updatePluginProviderAIKey({
url: `/workspaces/current/tool-providers/${pluginType}/credentials`,
body,
})
if (res.result === 'success')
return Promise.resolve({ status: ValidatedStatus.Success })
else
return Promise.resolve({ status: ValidatedStatus.Error, message: res.error })
}
catch (e: any) {
return Promise.resolve({ status: ValidatedStatus.Error, message: e.message })
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment