Unverified Commit bec998ab authored by Joel's avatar Joel Committed by GitHub

chore: remove universal chat code (#2194)

parent 77636945
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)
......@@ -16,7 +16,6 @@ export type ICardItemProps = {
onRemove: (id: string) => void
readonly?: boolean
}
// used in universal-chat
const CardItem: FC<ICardItemProps> = ({
className,
config,
......
......@@ -33,7 +33,7 @@ const AudioBtn = ({
if (value !== '') {
formData.append('text', removeCodeBlocks(value))
let url = '/universal-chat/text-to-audio'
let url = ''
let isPublic = false
if (params.token) {
......
......@@ -86,7 +86,7 @@ const VoiceInput = ({
const formData = new FormData()
formData.append('file', mp3File)
let url = '/universal-chat/audio-to-text'
let url = ''
let isPublic = false
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'
import type { DataSet } from '@/models/datasets'
type Props = {
modelId: string
providerName: string
plugins: Record<string, boolean>
dataSets: DataSet[]
}
const ConfigViewPanel: FC<Props> = ({
modelId,
providerName,
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}
providerName={providerName}
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(~@/assets/action.svg) center center no-repeat transparent;
background-size: 16px 16px;
/* mask-image: ; */
}
.panelBorder {
border: 0.5px solid rgba(0, 0, 0, .05);
}
'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/header/account-setting/model-provider-page/model-icon'
import ModelName from '@/app/components/header/account-setting/model-provider-page/model-name'
import { Google, WebReader, Wikipedia } from '@/app/components/base/icons/src/public/plugins'
import ConfigDetail from '@/app/components/explore/universal-chat/config-view/detail'
import type { DataSet } from '@/models/datasets'
import { useAgentThoughtCurrentProviderAndModelAndModelList } from '@/app/components/header/account-setting/model-provider-page/hooks'
export type ISummaryProps = {
modelId: string
providerName: string
plugins: Record<string, boolean>
dataSets: DataSet[]
}
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,
providerName,
plugins,
dataSets,
}) => {
const {
currentModel: currModel,
currentProvider,
} = useAgentThoughtCurrentProviderAndModelAndModelList(
{ provider: providerName, model: modelId },
)
// current_datetime is not configable and do not have icon
const pluginIds = Object.keys(plugins).filter(key => plugins[key] && key !== 'current_datetime')
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
provider={currentProvider}
modelName={currModel?.model}
className='!w-6 !h-6'
/>
<div className='ml-2 text-[13px] font-medium text-gray-900'>
<ModelName
modelItem={currModel!}
/>
</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}
providerName={providerName}
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}
/>
))}
</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'
import type { DataSet } from '@/models/datasets'
export type IConfigProps = {
className?: string
readonly?: boolean
modelId: string
providerName: string
onModelChange?: (modelId: string, providerName: string) => void
plugins: Record<string, boolean>
onPluginChange?: (key: string, value: boolean) => void
dataSets: DataSet[]
onDataSetsChange?: (contexts: DataSet[]) => void
}
const Config: FC<IConfigProps> = ({
className,
readonly,
modelId,
providerName,
onModelChange,
plugins,
onPluginChange,
dataSets,
onDataSetsChange,
}) => {
return (
<div className={className}>
<ModelConfig
readonly={readonly}
modelId={modelId}
providerName={providerName}
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 { useTranslation } from 'react-i18next'
import ModelSelector from '@/app/components/header/account-setting/model-provider-page/model-selector'
import { useProviderContext } from '@/context/provider-context'
export type IModelConfigProps = {
modelId: string
providerName: string
onChange?: (modelId: string, providerName: string) => void
readonly?: boolean
}
const ModelConfig: FC<IModelConfigProps> = ({
modelId,
providerName,
onChange,
readonly,
}) => {
const { t } = useTranslation()
const { agentThoughtModelList } = useProviderContext()
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>
<ModelSelector
triggerClassName={`${readonly && '!cursor-not-allowed !opacity-60'}`}
defaultModel={{ provider: providerName, model: modelId }}
modelList={agentThoughtModelList}
onSelect={(model) => {
onChange?.(model.model, model.provider)
}}
readonly={readonly}
/>
</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 { useModalContext } from '@/context/modal-context'
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 /> },
] as const
const Plugins: FC<IPluginsProps> = ({
readonly,
config,
onChange,
}) => {
const { t } = useTranslation()
const { setShowAccountSettingModal } = useModalContext()
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 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={() => setShowAccountSettingModal({ payload: 'plugin', onCancelCallback: async () => await checkSerpApiKey() })}>{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>
</>
)
}
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,
existConversationInfo,
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="100%" 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 justify-center'>
<div>
<div className='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 h-8 items-center'>
{Line}
</div>
<Config {...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;
}
......@@ -58,7 +58,6 @@ export type IMainProps = {
isInstalledApp?: boolean
installedAppInfo?: InstalledApp
isSupportPlugin?: boolean
isUniversalChat?: boolean
}
const Main: FC<IMainProps> = ({
......
......@@ -11,7 +11,6 @@ import AppInfo from '@/app/components/share/chat/sidebar/app-info'
// import Card from './card'
import type { ConversationItem, SiteInfo } from '@/models/share'
import { fetchConversations } from '@/service/share'
import { fetchConversations as fetchUniversalConversations } from '@/service/universal-chat'
export type ISidebarProps = {
copyRight: string
......@@ -25,7 +24,6 @@ export type ISidebarProps = {
isClearPinnedConversationList: boolean
isInstalledApp: boolean
installedAppId?: string
isUniversalChat?: boolean
siteInfo: SiteInfo
onMoreLoaded: (res: { data: ConversationItem[]; has_more: boolean }) => void
onPinnedMoreLoaded: (res: { data: ConversationItem[]; has_more: boolean }) => void
......@@ -50,7 +48,6 @@ const Sidebar: FC<ISidebarProps> = ({
isClearPinnedConversationList,
isInstalledApp,
installedAppId,
isUniversalChat,
siteInfo,
onMoreLoaded,
onPinnedMoreLoaded,
......@@ -66,13 +63,7 @@ const Sidebar: FC<ISidebarProps> = ({
const [hasPinned, setHasPinned] = useState(false)
const checkHasPinned = async () => {
let res: any
if (isUniversalChat)
res = await fetchUniversalConversations(undefined, true)
else
res = await fetchConversations(isInstalledApp, installedAppId, undefined, true)
const res = await fetchConversations(isInstalledApp, installedAppId, undefined, true) as any
setHasPinned(res.data.length > 0)
}
......@@ -85,13 +76,13 @@ const Sidebar: FC<ISidebarProps> = ({
checkHasPinned()
}, [controlUpdateList])
const maxListHeight = (isInstalledApp || isUniversalChat) ? 'max-h-[30vh]' : 'max-h-[40vh]'
const maxListHeight = (isInstalledApp) ? 'max-h-[30vh]' : 'max-h-[40vh]'
return (
<div
className={
cn(
(isInstalledApp || isUniversalChat) ? 'tablet:h-[calc(100vh_-_74px)]' : '',
(isInstalledApp) ? 'tablet:h-[calc(100vh_-_74px)]' : '',
'shrink-0 flex flex-col bg-white pc:w-[244px] tablet:w-[192px] mobile:w-[240px] border-r border-gray-200 mobile:h-screen',
)
}
......@@ -125,7 +116,6 @@ const Sidebar: FC<ISidebarProps> = ({
isClearConversationList={isClearPinnedConversationList}
isInstalledApp={isInstalledApp}
installedAppId={installedAppId}
isUniversalChat={isUniversalChat}
onMoreLoaded={onPinnedMoreLoaded}
isNoMore={isPinnedNoMore}
isPinned={true}
......@@ -149,7 +139,6 @@ const Sidebar: FC<ISidebarProps> = ({
isClearConversationList={isClearConversationList}
isInstalledApp={isInstalledApp}
installedAppId={installedAppId}
isUniversalChat={isUniversalChat}
onMoreLoaded={onMoreLoaded}
isNoMore={isNoMore}
isPinned={false}
......@@ -160,11 +149,9 @@ const Sidebar: FC<ISidebarProps> = ({
</div>
</div>
{!isUniversalChat && (
<div className="flex flex-shrink-0 pr-4 pb-4 pl-4">
<div className="text-gray-400 font-normal text-xs">© {copyRight} {(new Date()).getFullYear()}</div>
</div>
)}
</div>
)
}
......
......@@ -9,7 +9,6 @@ import RenameModal from '../rename-modal'
import Item from './item'
import type { ConversationItem } from '@/models/share'
import { fetchConversations, renameConversation } from '@/service/share'
import { fetchConversations as fetchUniversalConversations, renameConversation as renameUniversalConversation } from '@/service/universal-chat'
import Toast from '@/app/components/base/toast'
export type IListProps = {
......@@ -20,7 +19,6 @@ export type IListProps = {
onListChanged?: (newList: ConversationItem[]) => void
isClearConversationList: boolean
isInstalledApp: boolean
isUniversalChat?: boolean
installedAppId?: string
onMoreLoaded: (res: { data: ConversationItem[]; has_more: boolean }) => void
isNoMore: boolean
......@@ -38,7 +36,6 @@ const List: FC<IListProps> = ({
onListChanged,
isClearConversationList,
isInstalledApp,
isUniversalChat,
installedAppId,
onMoreLoaded,
isNoMore,
......@@ -56,11 +53,7 @@ const List: FC<IListProps> = ({
let lastId = !isClearConversationList ? list[list.length - 1]?.id : undefined
if (lastId === '-1')
lastId = undefined
let res: any
if (isUniversalChat)
res = await fetchUniversalConversations(lastId, isPinned)
else
res = await fetchConversations(isInstalledApp, installedAppId, lastId, isPinned)
const res = await fetchConversations(isInstalledApp, installedAppId, lastId, isPinned) as any
const { data: conversations, has_more }: any = res
onMoreLoaded({ data: conversations, has_more })
}
......@@ -93,10 +86,6 @@ const List: FC<IListProps> = ({
setIsSaving()
const currId = currentConversation.id
try {
if (isUniversalChat)
await renameUniversalConversation(currId, newName)
else
await renameConversation(isInstalledApp, installedAppId, currId, newName)
Toast.notify({
......
......@@ -52,8 +52,6 @@ export const MODEL_LIST = [
{ id: 'claude-instant-1', name: 'claude-instant-1', type: AppType.completion, provider: ProviderType.anthropic }, // set 30k
{ id: 'claude-2', name: 'claude-2', type: AppType.completion, provider: ProviderType.anthropic }, // set 30k
]
const UNIVERSAL_CHAT_MODEL_ID_LIST = ['gpt-3.5-turbo', 'gpt-3.5-turbo-16k', 'gpt-4', 'claude-2']
export const UNIVERSAL_CHAT_MODEL_LIST = MODEL_LIST.filter(({ id, type }) => UNIVERSAL_CHAT_MODEL_ID_LIST.includes(id) && (type === AppType.chat))
export const TONE_LIST = [
{
id: 1,
......
......@@ -36,45 +36,6 @@ const translation = {
Programming: 'Programming',
HR: 'HR',
},
universalChat: {
welcome: 'Start chat with Dify',
welcomeDescribe: 'Your AI conversation companion for personalized assistance',
model: 'Model',
plugins: {
name: 'Plugins',
google_search: {
name: 'Google Search',
more: {
left: 'Enable the plugin, ',
link: 'set up your SerpAPI key',
right: ' first.',
},
},
web_reader: {
name: 'Web Reader',
description: 'Get needed information from any web link',
},
wikipedia: {
name: 'Wikipedia',
},
},
thought: {
show: 'Show',
hide: 'Hide',
processOfThought: ' the process of thinking',
res: {
webReader: {
normal: 'Reading {url}',
hasPageInfo: 'Reading next page of {url}',
},
google: 'Searching Google {{query}}',
wikipedia: 'Searching Wikipedia {{query}}',
dataset: 'Retrieving Knowledge {datasetName}',
date: 'Searching date',
},
},
viewConfigDetailTip: 'In conversation, cannot change above settings',
},
}
export default translation
......@@ -36,45 +36,6 @@ const translation = {
Programming: 'Programação',
HR: 'RH',
},
universalChat: {
welcome: 'Iniciar chat com Dify',
welcomeDescribe: 'Seu companheiro de conversa de IA para assistência personalizada',
model: 'Modelo',
plugins: {
name: 'Plugins',
google_search: {
name: 'Pesquisa do Google',
more: {
left: 'Ative o plugin, ',
link: 'configure sua chave SerpAPI',
right: ' primeiro.',
},
},
web_reader: {
name: 'Leitor da Web',
description: 'Obtenha informações necessárias de qualquer link da web',
},
wikipedia: {
name: 'Wikipedia',
},
},
thought: {
show: 'Mostrar',
hide: 'Ocultar',
processOfThought: ' o processo de pensamento',
res: {
webReader: {
normal: 'Lendo {url}',
hasPageInfo: 'Lendo próxima página de {url}',
},
google: 'Pesquisando no Google {{query}}',
wikipedia: 'Pesquisando na Wikipedia {{query}}',
dataset: 'Recuperando Conhecimento {datasetName}',
date: 'Pesquisando data',
},
},
viewConfigDetailTip: 'Na conversa, não é possível alterar as configurações acima',
},
}
export default translation
......@@ -36,45 +36,6 @@ const translation = {
Programming: '编程',
HR: '人力资源',
},
universalChat: {
welcome: '开始和 Dify 聊天吧',
welcomeDescribe: '您的 AI 对话伴侣,为您提供个性化的帮助',
model: '模型',
plugins: {
name: '插件',
google_search: {
name: '谷歌搜索',
more: {
left: '启用插件,首先',
link: '设置您的 SerpAPI 密钥',
right: '',
},
},
web_reader: {
name: '解析链接',
description: '从任何网页链接获取所需信息',
},
wikipedia: {
name: '维基百科',
},
},
thought: {
show: '显示',
hide: '隐藏',
processOfThought: '思考过程',
res: {
webReader: {
normal: '解析链接 {url}',
hasPageInfo: '解析链接 {url} 的下一页',
},
google: '搜索谷歌 {{query}}',
wikipedia: '搜索维基百科 {{query}}',
dataset: '检索知识库 {datasetName}',
date: '查询日期',
},
},
viewConfigDetailTip: '在对话中,无法更改上述设置',
},
}
export default translation
import type { IOnCompleted, IOnData, IOnError, IOnMessageEnd, IOnThought } from './base'
import {
del, get, patch, post, ssePost,
} from './base'
import type { Feedbacktype } from '@/app/components/app/chat/type'
const baseUrl = 'universal-chat'
function getUrl(url: string) {
return `${baseUrl}/${url.startsWith('/') ? url.slice(1) : url}`
}
export const sendChatMessage = async (body: Record<string, any>, { onData, onCompleted, onError, onThought, onMessageEnd, getAbortController }: {
onData: IOnData
onCompleted: IOnCompleted
onError: IOnError
onThought: IOnThought
onMessageEnd: IOnMessageEnd
getAbortController?: (abortController: AbortController) => void
}) => {
return ssePost(getUrl('messages'), {
body: {
...body,
response_mode: 'streaming',
},
}, { onData, onCompleted, onThought, onError, getAbortController, onMessageEnd })
}
export const stopChatMessageResponding = async (taskId: string) => {
return post(getUrl(`messages/${taskId}/stop`))
}
export const fetchConversations = async (last_id?: string, pinned?: boolean, limit?: number) => {
return get(getUrl('conversations'), { params: { ...{ limit: limit || 20 }, ...(last_id ? { last_id } : {}), ...(pinned !== undefined ? { pinned } : {}) } })
}
export const pinConversation = async (id: string) => {
return patch(getUrl(`conversations/${id}/pin`))
}
export const unpinConversation = async (id: string) => {
return patch(getUrl(`conversations/${id}/unpin`))
}
export const delConversation = async (id: string) => {
return del(getUrl(`conversations/${id}`))
}
export const renameConversation = async (id: string, name: string) => {
return post(getUrl(`conversations/${id}/name`), { body: { name } })
}
export const generationConversationName = async (id: string) => {
return post(getUrl(`conversations/${id}/name`), { body: { auto_generate: true } })
}
export const fetchChatList = async (conversationId: string) => {
return get(getUrl('messages'), { params: { conversation_id: conversationId, limit: 20, last_id: '' } })
}
// init value. wait for server update
export const fetchAppParams = async () => {
return get(getUrl('parameters'))
}
export const updateFeedback = async ({ url, body }: { url: string; body: Feedbacktype }) => {
return post(getUrl(url), { body })
}
export const fetchMoreLikeThis = async (messageId: string) => {
return get(getUrl(`/messages/${messageId}/more-like-this`), {
params: {
response_mode: 'blocking',
},
})
}
export const fetchSuggestedQuestions = (messageId: string) => {
return get(getUrl(`/messages/${messageId}/suggested-questions`))
}
export const audioToText = (url: string, body: FormData) => {
return post(url, { body }, { bodyStringify: false, deleteContentType: true }) as Promise<{ text: string }>
}
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