merge main

This commit is contained in:
zxhlyh
2025-05-19 18:11:45 +08:00
97 changed files with 1709 additions and 674 deletions

View File

@ -247,7 +247,7 @@ const AppInfo = ({ expand }: IAppInfoProps) => {
</div>
{/* description */}
{appDetail.description && (
<div className='system-xs-regular text-text-tertiary'>{appDetail.description}</div>
<div className='system-xs-regular overflow-wrap-anywhere w-full max-w-full whitespace-normal break-words text-text-tertiary'>{appDetail.description}</div>
)}
{/* operations */}
<div className='flex flex-wrap items-center gap-1 self-stretch'>

View File

@ -24,7 +24,7 @@ import {
PortalToFollowElemContent,
PortalToFollowElemTrigger,
} from '@/app/components/base/portal-to-follow-elem'
import { WEB_PREFIX } from '@/config'
import { basePath } from '@/utils/var'
import { fetchInstalledAppList } from '@/service/explore'
import EmbeddedModal from '@/app/components/app/overview/embedded'
import { useStore as useAppStore } from '@/app/components/app/store'
@ -76,7 +76,7 @@ const AppPublisher = ({
const appDetail = useAppStore(state => state.appDetail)
const { app_base_url: appBaseURL = '', access_token: accessToken = '' } = appDetail?.site ?? {}
const appMode = (appDetail?.mode !== 'completion' && appDetail?.mode !== 'workflow') ? 'chat' : appDetail.mode
const appURL = `${appBaseURL}/${appMode}/${accessToken}`
const appURL = `${appBaseURL}${basePath}/${appMode}/${accessToken}`
const isChatApp = ['chat', 'agent-chat', 'completion'].includes(appDetail?.mode || '')
const language = useGetLanguage()
@ -121,7 +121,7 @@ const AppPublisher = ({
try {
const { installed_apps }: any = await fetchInstalledAppList(appDetail?.id) || {}
if (installed_apps?.length > 0)
window.open(`${WEB_PREFIX}/explore/installed/${installed_apps[0].id}`, '_blank')
window.open(`${basePath}/explore/installed/${installed_apps[0].id}`, '_blank')
else
throw new Error('No app found in Explore')
}

View File

@ -14,8 +14,8 @@ const SuggestedAction = ({ icon, link, disabled, children, className, ...props }
target='_blank'
rel='noreferrer'
className={classNames(
'flex justify-start items-center gap-2 py-2 px-2.5 bg-background-section-burn rounded-lg transition-colors [&:not(:first-child)]:mt-1',
disabled ? 'shadow-xs opacity-30 cursor-not-allowed' : 'text-text-secondary hover:bg-state-accent-hover hover:text-text-accent cursor-pointer',
'flex justify-start items-center gap-2 py-2 px-2.5 bg-background-section-burn rounded-lg text-text-secondary transition-colors [&:not(:first-child)]:mt-1',
disabled ? 'shadow-xs opacity-30 cursor-not-allowed' : 'hover:bg-state-accent-hover hover:text-text-accent cursor-pointer',
className,
)}
{...props}

View File

@ -14,6 +14,7 @@ import Loading from '@/app/components/base/loading'
import Badge from '@/app/components/base/badge'
import { useKnowledge } from '@/hooks/use-knowledge'
import cn from '@/utils/classnames'
import { basePath } from '@/utils/var'
export type ISelectDataSetProps = {
isShow: boolean
@ -111,7 +112,7 @@ const SelectDataSet: FC<ISelectDataSetProps> = ({
}}
>
<span className='text-text-tertiary'>{t('appDebug.feature.dataSet.noDataSet')}</span>
<Link href={'/datasets/create'} className='font-normal text-text-accent'>{t('appDebug.feature.dataSet.toCreate')}</Link>
<Link href={`${basePath}/datasets/create`} className='font-normal text-text-accent'>{t('appDebug.feature.dataSet.toCreate')}</Link>
</div>
)}

View File

@ -14,7 +14,7 @@ import type { AppIconSelection } from '../../base/app-icon-picker'
import Button from '@/app/components/base/button'
import Divider from '@/app/components/base/divider'
import cn from '@/utils/classnames'
import { WEB_PREFIX } from '@/config'
import { basePath } from '@/utils/var'
import AppsContext, { useAppContext } from '@/context/app-context'
import { useProviderContext } from '@/context/provider-context'
import { ToastContext } from '@/app/components/base/toast'
@ -353,11 +353,11 @@ function AppScreenShot({ mode, show }: { mode: AppMode; show: boolean }) {
'workflow': 'Workflow',
}
return <picture>
<source media="(resolution: 1x)" srcSet={`${WEB_PREFIX}/screenshots/${theme}/${modeToImageMap[mode]}.png`} />
<source media="(resolution: 2x)" srcSet={`${WEB_PREFIX}/screenshots/${theme}/${modeToImageMap[mode]}@2x.png`} />
<source media="(resolution: 3x)" srcSet={`${WEB_PREFIX}/screenshots/${theme}/${modeToImageMap[mode]}@3x.png`} />
<source media="(resolution: 1x)" srcSet={`${basePath}/screenshots/${theme}/${modeToImageMap[mode]}.png`} />
<source media="(resolution: 2x)" srcSet={`${basePath}/screenshots/${theme}/${modeToImageMap[mode]}@2x.png`} />
<source media="(resolution: 3x)" srcSet={`${basePath}/screenshots/${theme}/${modeToImageMap[mode]}@3x.png`} />
<Image className={show ? '' : 'hidden'}
src={`${WEB_PREFIX}/screenshots/${theme}/${modeToImageMap[mode]}.png`}
src={`${basePath}/screenshots/${theme}/${modeToImageMap[mode]}.png`}
alt='App Screen Shot'
width={664} height={448} />
</picture>

View File

@ -7,6 +7,7 @@ import { usePathname } from 'next/navigation'
import { useDebounce } from 'ahooks'
import { omit } from 'lodash-es'
import dayjs from 'dayjs'
import { basePath } from '@/utils/var'
import { Trans, useTranslation } from 'react-i18next'
import List from './list'
import Filter, { TIME_PERIOD_MAPPING } from './filter'
@ -109,7 +110,7 @@ const Logs: FC<ILogsProps> = ({ appDetail }) => {
? <Loading type='app' />
: total > 0
? <List logs={isChatMode ? chatConversations : completionConversations} appDetail={appDetail} onRefresh={isChatMode ? mutateChatList : mutateCompletionList} />
: <EmptyElement appUrl={`${appDetail.site.app_base_url}/${getWebAppType(appDetail.mode)}/${appDetail.site.access_token}`} />
: <EmptyElement appUrl={`${appDetail.site.app_base_url}${basePath}/${getWebAppType(appDetail.mode)}/${appDetail.site.access_token}`} />
}
{/* Show Pagination only if the total is more than the limit */}
{(total && total > APP_PAGE_LIMIT)

View File

@ -17,6 +17,7 @@ import type { ConfigParams } from './settings'
import Tooltip from '@/app/components/base/tooltip'
import AppBasic from '@/app/components/app-sidebar/basic'
import { asyncRunSafe, randomString } from '@/utils'
import { basePath } from '@/utils/var'
import Button from '@/app/components/base/button'
import Switch from '@/app/components/base/switch'
import Divider from '@/app/components/base/divider'
@ -88,7 +89,7 @@ function AppCard({
const runningStatus = isApp ? appInfo.enable_site : appInfo.enable_api
const { app_base_url, access_token } = appInfo.site ?? {}
const appMode = (appInfo.mode !== 'completion' && appInfo.mode !== 'workflow') ? 'chat' : appInfo.mode
const appUrl = `${app_base_url}/${appMode}/${access_token}`
const appUrl = `${app_base_url}${basePath}/${appMode}/${access_token}`
const apiUrl = appInfo?.api_base_url
const genClickFuncByName = (opName: string) => {

View File

@ -13,6 +13,7 @@ import { IS_CE_EDITION } from '@/config'
import type { SiteInfo } from '@/models/share'
import { useThemeContext } from '@/app/components/base/chat/embedded-chatbot/theme/theme-context'
import ActionButton from '@/app/components/base/action-button'
import { basePath } from '@/utils/var'
import cn from '@/utils/classnames'
type Props = {
@ -28,7 +29,7 @@ const OPTION_MAP = {
iframe: {
getContent: (url: string, token: string) =>
`<iframe
src="${url}/chatbot/${token}"
src="${url}${basePath}/chatbot/${token}"
style="width: 100%; height: 100%; min-height: 700px"
frameborder="0"
allow="microphone">
@ -43,7 +44,7 @@ const OPTION_MAP = {
isDev: true`
: ''}${IS_CE_EDITION
? `,
baseUrl: '${url}'`
baseUrl: '${url}${basePath}'`
: ''},
systemVariables: {
// user_id: 'YOU CAN DEFINE USER ID HERE',
@ -52,7 +53,7 @@ const OPTION_MAP = {
}
</script>
<script
src="${url}/embed.min.js"
src="${url}${basePath}/embed.min.js"
id="${token}"
defer>
</script>
@ -67,7 +68,7 @@ const OPTION_MAP = {
</style>`,
},
chromePlugin: {
getContent: (url: string, token: string) => `ChatBot URL: ${url}/chatbot/${token}`,
getContent: (url: string, token: string) => `ChatBot URL: ${url}${basePath}/chatbot/${token}`,
},
}
const prefixEmbedded = 'appOverview.overview.appInfo.embedded'

View File

@ -11,6 +11,7 @@ import timezone from 'dayjs/plugin/timezone'
import { Trans, useTranslation } from 'react-i18next'
import Link from 'next/link'
import List from './list'
import { basePath } from '@/utils/var'
import Filter, { TIME_PERIOD_MAPPING } from './filter'
import Pagination from '@/app/components/base/pagination'
import Loading from '@/app/components/base/loading'
@ -100,7 +101,7 @@ const Logs: FC<ILogsProps> = ({ appDetail }) => {
? <Loading type='app' />
: total > 0
? <List logs={workflowLogs} appDetail={appDetail} onRefresh={mutate} />
: <EmptyElement appUrl={`${appDetail.site.app_base_url}/${getWebAppType(appDetail.mode)}/${appDetail.site.access_token}`} />
: <EmptyElement appUrl={`${appDetail.site.app_base_url}${basePath}/${getWebAppType(appDetail.mode)}/${appDetail.site.access_token}`} />
}
{/* Show Pagination only if the total is more than the limit */}
{(total && total > APP_PAGE_LIMIT)

View File

@ -1,8 +1,8 @@
'use client'
import type { FC } from 'react'
import { WEB_PREFIX } from '@/config'
import classNames from '@/utils/classnames'
import useTheme from '@/hooks/use-theme'
import { basePath } from '@/utils/var'
export type LogoStyle = 'default' | 'monochromeWhite'
@ -35,7 +35,7 @@ const DifyLogo: FC<DifyLogoProps> = ({
return (
<img
src={`${WEB_PREFIX}${logoPathMap[themedStyle]}`}
src={`${basePath}${logoPathMap[themedStyle]}`}
className={classNames('block object-contain', logoSizeMap[size], className)}
alt='Dify logo'
/>

View File

@ -1,5 +1,5 @@
import type { FC } from 'react'
import { WEB_PREFIX } from '@/config'
import { basePath } from '@/utils/var'
type LogoEmbeddedChatAvatarProps = {
className?: string
@ -9,7 +9,7 @@ const LogoEmbeddedChatAvatar: FC<LogoEmbeddedChatAvatarProps> = ({
}) => {
return (
<img
src={`${WEB_PREFIX}/logo/logo-embedded-chat-avatar.png`}
src={`${basePath}/logo/logo-embedded-chat-avatar.png`}
className={`block h-10 w-10 ${className}`}
alt='logo'
/>

View File

@ -1,6 +1,6 @@
import classNames from '@/utils/classnames'
import type { FC } from 'react'
import { WEB_PREFIX } from '@/config'
import { basePath } from '@/utils/var'
type LogoEmbeddedChatHeaderProps = {
className?: string
@ -14,7 +14,7 @@ const LogoEmbeddedChatHeader: FC<LogoEmbeddedChatHeaderProps> = ({
<source media="(resolution: 2x)" srcSet='/logo/logo-embedded-chat-header@2x.png' />
<source media="(resolution: 3x)" srcSet='/logo/logo-embedded-chat-header@3x.png' />
<img
src={`${WEB_PREFIX}/logo/logo-embedded-chat-header.png`}
src={`${basePath}/logo/logo-embedded-chat-header.png`}
alt='logo'
className={classNames('block h-6 w-auto', className)}
/>

View File

@ -0,0 +1,22 @@
'use client'
import type { FC } from 'react'
import { basePath } from '@/utils/var'
import classNames from '@/utils/classnames'
type LogoSiteProps = {
className?: string
}
const LogoSite: FC<LogoSiteProps> = ({
className,
}) => {
return (
<img
src={`${basePath}/logo/logo.png`}
className={classNames('block w-[22.651px] h-[24.5px]', className)}
alt='logo'
/>
)
}
export default LogoSite

View File

@ -15,7 +15,7 @@ export default function Group({ children, value, onChange, className = '' }: TRa
onChange?.(value)
}
return (
<div className={cn('flex items-center bg-gray-50', s.container, className)}>
<div className={cn('flex items-center bg-workflow-block-parma-bg text-text-secondary', s.container, className)}>
<RadioGroupContext.Provider value={{ value, onChange: onRadioChange }}>
{children}
</RadioGroupContext.Provider>

View File

@ -68,7 +68,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
</Property>
<Property name='process_rule' type='object' key='process_rule'>
Processing rules
- <code>mode</code> (string) Cleaning, segmentation mode, automatic / custom
- <code>mode</code> (string) Cleaning, segmentation mode, automatic / custom / hierarchical
- <code>rules</code> (object) Custom rules (in automatic mode, this field is empty)
- <code>pre_processing_rules</code> (array[object]) Preprocessing rules
- <code>id</code> (string) Unique identifier for the preprocessing rule
@ -203,7 +203,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
- <code>doc_language</code> In Q&A mode, specify the language of the document, for example: <code>English</code>, <code>Chinese</code>
- <code>process_rule</code> Processing rules
- <code>mode</code> (string) Cleaning, segmentation mode, automatic / custom
- <code>mode</code> (string) Cleaning, segmentation mode, automatic / custom / hierarchical
- <code>rules</code> (object) Custom rules (in automatic mode, this field is empty)
- <code>pre_processing_rules</code> (array[object]) Preprocessing rules
- <code>id</code> (string) Unique identifier for the preprocessing rule
@ -783,7 +783,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
</Property>
<Property name='process_rule' type='object' key='process_rule'>
Processing rules
- <code>mode</code> (string) Cleaning, segmentation mode, automatic / custom
- <code>mode</code> (string) Cleaning, segmentation mode, automatic / custom / hierarchical
- <code>rules</code> (object) Custom rules (in automatic mode, this field is empty)
- <code>pre_processing_rules</code> (array[object]) Preprocessing rules
- <code>id</code> (string) Unique identifier for the preprocessing rule
@ -885,7 +885,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
</Property>
<Property name='process_rule' type='object' key='process_rule'>
Processing rules
- <code>mode</code> (string) Cleaning, segmentation mode, automatic / custom
- <code>mode</code> (string) Cleaning, segmentation mode, automatic / custom / hierarchical
- <code>rules</code> (object) Custom rules (in automatic mode, this field is empty)
- <code>pre_processing_rules</code> (array[object]) Preprocessing rules
- <code>id</code> (string) Unique identifier for the preprocessing rule

View File

@ -69,7 +69,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
</Property>
<Property name='process_rule' type='object' key='process_rule'>
处理规则
- <code>mode</code> (string) 清洗、分段模式 automatic 自动 / custom 自定义
- <code>mode</code> (string) 清洗、分段模式 automatic 自动 / custom 自定义 / hierarchical 父子
- <code>rules</code> (object) 自定义规则(自动模式下,该字段为空)
- <code>pre_processing_rules</code> (array[object]) 预处理规则
- <code>id</code> (string) 预处理规则的唯一标识符
@ -207,7 +207,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
- <code>doc_language</code> 在 Q&A 模式下,指定文档的语言,例如:<code>English</code>、<code>Chinese</code>
- <code>process_rule</code> 处理规则
- <code>mode</code> (string) 清洗、分段模式 automatic 自动 / custom 自定义
- <code>mode</code> (string) 清洗、分段模式 automatic 自动 / custom 自定义 / hierarchical 父子
- <code>rules</code> (object) 自定义规则(自动模式下,该字段为空)
- <code>pre_processing_rules</code> (array[object]) 预处理规则
- <code>id</code> (string) 预处理规则的唯一标识符
@ -790,7 +790,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
</Property>
<Property name='process_rule' type='object' key='process_rule'>
处理规则(选填)
- <code>mode</code> (string) 清洗、分段模式 automatic 自动 / custom 自定义
- <code>mode</code> (string) 清洗、分段模式 automatic 自动 / custom 自定义 / hierarchical 父子
- <code>rules</code> (object) 自定义规则(自动模式下,该字段为空)
- <code>pre_processing_rules</code> (array[object]) 预处理规则
- <code>id</code> (string) 预处理规则的唯一标识符
@ -892,7 +892,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, PropertyInstructi
</Property>
<Property name='process_rule' type='object' key='process_rule'>
处理规则(选填)
- <code>mode</code> (string) 清洗、分段模式 automatic 自动 / custom 自定义
- <code>mode</code> (string) 清洗、分段模式 automatic 自动 / custom 自定义 / hierarchical 父子
- <code>rules</code> (object) 自定义规则(自动模式下,该字段为空)
- <code>pre_processing_rules</code> (array[object]) 预处理规则
- <code>id</code> (string) 预处理规则的唯一标识符

View File

@ -248,7 +248,7 @@ The text generation application offers non-session support and is ideal for tran
</Col>
<Col sticky>
### Request Example
<CodeGroup title="Request" tag="POST" label="/files/upload" targetCode={`curl -X POST '${props.appDetail.api_base_url}/files/upload' \\\n--header 'Authorization: Bearer {api_key}' \\\n--form 'file=@localfile;type=image/[png|jpeg|jpg|webp|gif] \\\n--form 'user=abc-123'`}>
<CodeGroup title="Request" tag="POST" label="/files/upload" targetCode={`curl -X POST '${props.appDetail.api_base_url}/files/upload' \\\n--header 'Authorization: Bearer {api_key}' \\\n--form 'file=@localfile;type=image/[png|jpeg|jpg|webp|gif]' \\\n--form 'user=abc-123'`}>
```bash {{ title: 'cURL' }}
curl -X POST '${props.appDetail.api_base_url}/files/upload' \

View File

@ -247,7 +247,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, Paragraph } from
</Col>
<Col sticky>
### リクエスト例
<CodeGroup title="Request" tag="POST" label="/files/upload" targetCode={`curl -X POST '${props.appDetail.api_base_url}/files/upload' \\\n--header 'Authorization: Bearer {api_key}' \\\n--form 'file=@localfile;type=image/[png|jpeg|jpg|webp|gif] \\\n--form 'user=abc-123'`}>
<CodeGroup title="Request" tag="POST" label="/files/upload" targetCode={`curl -X POST '${props.appDetail.api_base_url}/files/upload' \\\n--header 'Authorization: Bearer {api_key}' \\\n--form 'file=@localfile;type=image/[png|jpeg|jpg|webp|gif]' \\\n--form 'user=abc-123'`}>
```bash {{ title: 'cURL' }}
curl -X POST '${props.appDetail.api_base_url}/files/upload' \

View File

@ -226,7 +226,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx'
</Col>
<Col sticky>
<CodeGroup title="Request" tag="POST" label="/files/upload" targetCode={`curl -X POST '${props.appDetail.api_base_url}/files/upload' \\\n--header 'Authorization: Bearer {api_key}' \\\n--form 'file=@localfile;type=image/[png|jpeg|jpg|webp|gif] \\\n--form 'user=abc-123'`}>
<CodeGroup title="Request" tag="POST" label="/files/upload" targetCode={`curl -X POST '${props.appDetail.api_base_url}/files/upload' \\\n--header 'Authorization: Bearer {api_key}' \\\n--form 'file=@localfile;type=image/[png|jpeg|jpg|webp|gif]' \\\n--form 'user=abc-123'`}>
```bash {{ title: 'cURL' }}
curl -X POST '${props.appDetail.api_base_url}/files/upload' \

View File

@ -352,7 +352,7 @@ Chat applications support session persistence, allowing previous chat history to
</Col>
<Col sticky>
### Request Example
<CodeGroup title="Request" tag="POST" label="/files/upload" targetCode={`curl -X POST '${props.appDetail.api_base_url}/files/upload' \\\n--header 'Authorization: Bearer {api_key}' \\\n--form 'file=@localfile;type=image/[png|jpeg|jpg|webp|gif] \\\n--form 'user=abc-123'`}>
<CodeGroup title="Request" tag="POST" label="/files/upload" targetCode={`curl -X POST '${props.appDetail.api_base_url}/files/upload' \\\n--header 'Authorization: Bearer {api_key}' \\\n--form 'file=@localfile;type=image/[png|jpeg|jpg|webp|gif]' \\\n--form 'user=abc-123'`}>
```bash {{ title: 'cURL' }}
curl -X POST '${props.appDetail.api_base_url}/files/upload' \
@ -1165,6 +1165,13 @@ Chat applications support session persistence, allowing previous chat history to
- `enabled` (bool) Whether it is enabled
- `speech_to_text` (object) Speech to text
- `enabled` (bool) Whether it is enabled
- `text_to_speech` (object) Text to speech
- `enabled` (bool) Whether it is enabled
- `voice` (string) Voice type
- `language` (string) Language
- `autoPlay` (string) Auto play
- `enabled` Enabled
- `disabled` Disabled
- `retriever_resource` (object) Citation and Attribution
- `enabled` (bool) Whether it is enabled
- `annotation_reply` (object) Annotation reply
@ -1220,6 +1227,12 @@ Chat applications support session persistence, allowing previous chat history to
"speech_to_text": {
"enabled": true
},
"text_to_speech": {
"enabled": true,
"voice": "sambert-zhinan-v1",
"language": "zh-Hans",
"autoPlay": "disabled"
},
"retriever_resource": {
"enabled": true
},

View File

@ -352,7 +352,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, Paragraph } from
</Col>
<Col sticky>
### リクエスト例
<CodeGroup title="リクエスト" tag="POST" label="/files/upload" targetCode={`curl -X POST '${props.appDetail.api_base_url}/files/upload' \\\n--header 'Authorization: Bearer {api_key}' \\\n--form 'file=@localfile;type=image/[png|jpeg|jpg|webp|gif] \\\n--form 'user=abc-123'`}>
<CodeGroup title="リクエスト" tag="POST" label="/files/upload" targetCode={`curl -X POST '${props.appDetail.api_base_url}/files/upload' \\\n--header 'Authorization: Bearer {api_key}' \\\n--form 'file=@localfile;type=image/[png|jpeg|jpg|webp|gif]' \\\n--form 'user=abc-123'`}>
```bash {{ title: 'cURL' }}
curl -X POST '${props.appDetail.api_base_url}/files/upload' \
@ -1165,6 +1165,13 @@ import { Row, Col, Properties, Property, Heading, SubProperty, Paragraph } from
- `enabled` (bool) 有効かどうか
- `speech_to_text` (object) 音声からテキストへ
- `enabled` (bool) 有効かどうか
- `text_to_speech` (object) テキストから音声へ
- `enabled` (bool) 有効かどうか
- `voice` (string) 音声タイプ
- `language` (string) 言語
- `autoPlay` (string) 自動再生
- `enabled` 有効
- `disabled` 無効
- `retriever_resource` (object) 引用と帰属
- `enabled` (bool) 有効かどうか
- `annotation_reply` (object) 注釈返信
@ -1220,6 +1227,12 @@ import { Row, Col, Properties, Property, Heading, SubProperty, Paragraph } from
"speech_to_text": {
"enabled": true
},
"text_to_speech": {
"enabled": true,
"voice": "sambert-zhinan-v1",
"language": "zh-Hans",
"autoPlay": "disabled"
},
"retriever_resource": {
"enabled": true
},

View File

@ -362,7 +362,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx'
</Col>
<Col sticky>
<CodeGroup title="Request" tag="POST" label="/files/upload" targetCode={`curl -X POST '${props.appDetail.api_base_url}/files/upload' \\\n--header 'Authorization: Bearer {api_key}' \\\n--form 'file=@localfile;type=image/[png|jpeg|jpg|webp|gif] \\\n--form 'user=abc-123'`}>
<CodeGroup title="Request" tag="POST" label="/files/upload" targetCode={`curl -X POST '${props.appDetail.api_base_url}/files/upload' \\\n--header 'Authorization: Bearer {api_key}' \\\n--form 'file=@localfile;type=image/[png|jpeg|jpg|webp|gif]' \\\n--form 'user=abc-123'`}>
```bash {{ title: 'cURL' }}
curl -X POST '${props.appDetail.api_base_url}/files/upload' \
@ -1199,6 +1199,13 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx'
- `enabled` (bool) 是否开启
- `speech_to_text` (object) 语音转文本
- `enabled` (bool) 是否开启
- `text_to_speech` (object) 文本转语音
- `enabled` (bool) 是否开启
- `voice` (string) 语音类型
- `language` (string) 语言
- `autoPlay` (string) 自动播放
- `enabled` 开启
- `disabled` 关闭
- `retriever_resource` (object) 引用和归属
- `enabled` (bool) 是否开启
- `annotation_reply` (object) 标记回复

View File

@ -315,7 +315,7 @@ Chat applications support session persistence, allowing previous chat history to
</Col>
<Col sticky>
### Request Example
<CodeGroup title="Request" tag="POST" label="/files/upload" targetCode={`curl -X POST '${props.appDetail.api_base_url}/files/upload' \\\n--header 'Authorization: Bearer {api_key}' \\\n--form 'file=@localfile;type=image/[png|jpeg|jpg|webp|gif] \\\n--form 'user=abc-123'`}>
<CodeGroup title="Request" tag="POST" label="/files/upload" targetCode={`curl -X POST '${props.appDetail.api_base_url}/files/upload' \\\n--header 'Authorization: Bearer {api_key}' \\\n--form 'file=@localfile;type=image/[png|jpeg|jpg|webp|gif]' \\\n--form 'user=abc-123'`}>
```bash {{ title: 'cURL' }}
curl -X POST '${props.appDetail.api_base_url}/files/upload' \
@ -1201,6 +1201,13 @@ Chat applications support session persistence, allowing previous chat history to
- `enabled` (bool) Whether it is enabled
- `speech_to_text` (object) Speech to text
- `enabled` (bool) Whether it is enabled
- `text_to_speech` (object) Text to speech
- `enabled` (bool) Whether it is enabled
- `voice` (string) Voice type
- `language` (string) Language
- `autoPlay` (string) Auto play
- `enabled` Enabled
- `disabled` Disabled
- `retriever_resource` (object) Citation and Attribution
- `enabled` (bool) Whether it is enabled
- `annotation_reply` (object) Annotation reply
@ -1256,6 +1263,12 @@ Chat applications support session persistence, allowing previous chat history to
"speech_to_text": {
"enabled": true
},
"text_to_speech": {
"enabled": true,
"voice": "sambert-zhinan-v1",
"language": "zh-Hans",
"autoPlay": "disabled"
},
"retriever_resource": {
"enabled": true
},

View File

@ -315,7 +315,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, Paragraph } from
</Col>
<Col sticky>
### リクエスト例
<CodeGroup title="リクエスト" tag="POST" label="/files/upload" targetCode={`curl -X POST '${props.appDetail.api_base_url}/files/upload' \\\n--header 'Authorization: Bearer {api_key}' \\\n--form 'file=@localfile;type=image/[png|jpeg|jpg|webp|gif] \\\n--form 'user=abc-123'`}>
<CodeGroup title="リクエスト" tag="POST" label="/files/upload" targetCode={`curl -X POST '${props.appDetail.api_base_url}/files/upload' \\\n--header 'Authorization: Bearer {api_key}' \\\n--form 'file=@localfile;type=image/[png|jpeg|jpg|webp|gif]' \\\n--form 'user=abc-123'`}>
```bash {{ title: 'cURL' }}
curl -X POST '${props.appDetail.api_base_url}/files/upload' \
@ -1192,6 +1192,13 @@ import { Row, Col, Properties, Property, Heading, SubProperty, Paragraph } from
- `enabled` (bool) 有効かどうか
- `speech_to_text` (object) 音声からテキストへ
- `enabled` (bool) 有効かどうか
- `text_to_speech` (object) テキストから音声へ
- `enabled` (bool) 有効かどうか
- `voice` (string) 音声タイプ
- `language` (string) 言語
- `autoPlay` (string) 自動再生
- `enabled` 有効
- `disabled` 無効
- `retriever_resource` (object) 引用と帰属
- `enabled` (bool) 有効かどうか
- `annotation_reply` (object) 注釈返信
@ -1247,6 +1254,12 @@ import { Row, Col, Properties, Property, Heading, SubProperty, Paragraph } from
"speech_to_text": {
"enabled": true
},
"text_to_speech": {
"enabled": true,
"voice": "sambert-zhinan-v1",
"language": "zh-Hans",
"autoPlay": "disabled"
},
"retriever_resource": {
"enabled": true
},

View File

@ -333,7 +333,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx'
</Col>
<Col sticky>
<CodeGroup title="Request" tag="POST" label="/files/upload" targetCode={`curl -X POST '${props.appDetail.api_base_url}/files/upload' \\\n--header 'Authorization: Bearer {api_key}' \\\n--form 'file=@localfile;type=image/[png|jpeg|jpg|webp|gif] \\\n--form 'user=abc-123'`}>
<CodeGroup title="Request" tag="POST" label="/files/upload" targetCode={`curl -X POST '${props.appDetail.api_base_url}/files/upload' \\\n--header 'Authorization: Bearer {api_key}' \\\n--form 'file=@localfile;type=image/[png|jpeg|jpg|webp|gif]' \\\n--form 'user=abc-123'`}>
```bash {{ title: 'cURL' }}
curl -X POST '${props.appDetail.api_base_url}/files/upload' \
@ -1204,6 +1204,13 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx'
- `enabled` (bool) 是否开启
- `speech_to_text` (object) 语音转文本
- `enabled` (bool) 是否开启
- `text_to_speech` (object) 文本转语音
- `enabled` (bool) 是否开启
- `voice` (string) 语音类型
- `language` (string) 语言
- `autoPlay` (string) 自动播放
- `enabled` 开启
- `disabled` 关闭
- `retriever_resource` (object) 引用和归属
- `enabled` (bool) 是否开启
- `annotation_reply` (object) 标记回复

View File

@ -476,7 +476,7 @@ Workflow applications offers non-session support and is ideal for translation, a
</Col>
<Col sticky>
### Request Example
<CodeGroup title="Request" tag="POST" label="/files/upload" targetCode={`curl -X POST '${props.appDetail.api_base_url}/files/upload' \\\n--header 'Authorization: Bearer {api_key}' \\\n--form 'file=@localfile;type=image/[png|jpeg|jpg|webp|gif] \\\n--form 'user=abc-123'`}>
<CodeGroup title="Request" tag="POST" label="/files/upload" targetCode={`curl -X POST '${props.appDetail.api_base_url}/files/upload' \\\n--header 'Authorization: Bearer {api_key}' \\\n--form 'file=@localfile;type=image/[png|jpeg|jpg|webp|gif]' \\\n--form 'user=abc-123'`}>
```bash {{ title: 'cURL' }}
curl -X POST '${props.appDetail.api_base_url}/files/upload' \

View File

@ -479,7 +479,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty, Paragraph } from
</Col>
<Col sticky>
### リクエスト例
<CodeGroup title="リクエスト" tag="POST" label="/files/upload" targetCode={`curl -X POST '${props.appDetail.api_base_url}/files/upload' \\\n--header 'Authorization: Bearer {api_key}' \\\n--form 'file=@localfile;type=image/[png|jpeg|jpg|webp|gif] \\\n--form 'user=abc-123'`}>
<CodeGroup title="リクエスト" tag="POST" label="/files/upload" targetCode={`curl -X POST '${props.appDetail.api_base_url}/files/upload' \\\n--header 'Authorization: Bearer {api_key}' \\\n--form 'file=@localfile;type=image/[png|jpeg|jpg|webp|gif]' \\\n--form 'user=abc-123'`}>
```bash {{ title: 'cURL' }}
curl -X POST '${props.appDetail.api_base_url}/files/upload' \

View File

@ -470,7 +470,7 @@ Workflow 应用无会话支持,适合用于翻译/文章写作/总结 AI 等
</Col>
<Col sticky>
<CodeGroup title="Request" tag="POST" label="/files/upload" targetCode={`curl -X POST '${props.appDetail.api_base_url}/files/upload' \\\n--header 'Authorization: Bearer {api_key}' \\\n--form 'file=@localfile;type=image/[png|jpeg|jpg|webp|gif] \\\n--form 'user=abc-123'`}>
<CodeGroup title="Request" tag="POST" label="/files/upload" targetCode={`curl -X POST '${props.appDetail.api_base_url}/files/upload' \\\n--header 'Authorization: Bearer {api_key}' \\\n--form 'file=@localfile;type=image/[png|jpeg|jpg|webp|gif]' \\\n--form 'user=abc-123'`}>
```bash {{ title: 'cURL' }}
curl -X POST '${props.appDetail.api_base_url}/files/upload' \

View File

@ -4,7 +4,7 @@ import { useTranslation } from 'react-i18next'
import { Menu, MenuButton, MenuItems, Transition } from '@headlessui/react'
import { RiArrowDownSLine } from '@remixicon/react'
import cn from '@/utils/classnames'
import { WEB_PREFIX } from '@/config'
import { basePath } from '@/utils/var'
import PlanBadge from '@/app/components/header/plan-badge'
import { switchWorkspace } from '@/service/common'
import { useWorkspacesContext } from '@/context/workspace-context'
@ -23,7 +23,7 @@ const WorkplaceSelector = () => {
return
await switchWorkspace({ url: '/workspaces/switch', body: { tenant_id } })
notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
location.assign(WEB_PREFIX)
location.assign(`${location.origin}${basePath}`)
}
catch {
notify({ type: 'error', message: t('common.provider.saveFailed') })

View File

@ -2,7 +2,6 @@
import cn from '@/utils/classnames'
import Modal from '@/app/components/base/modal'
import Input from '@/app/components/base/input'
import { WEB_PREFIX } from '@/config'
import { useTranslation } from 'react-i18next'
import { useState } from 'react'
import { useContext } from 'use-context-selector'
@ -34,7 +33,7 @@ const EditWorkspaceModal = ({
},
})
notify({ type: 'success', message: t('common.actionMsg.modifiedSuccessfully') })
location.assign(WEB_PREFIX)
location.assign(`${location.origin}`)
}
catch {
notify({ type: 'error', message: t('common.actionMsg.modifiedUnsuccessfully') })

View File

@ -1,5 +1,6 @@
import type { FC } from 'react'
import type { ModelProvider } from '../declarations'
import { basePath } from '@/utils/var'
import { useLanguage } from '../hooks'
import { Openai } from '@/app/components/base/icons/src/vender/other'
import { AnthropicDark, AnthropicLight } from '@/app/components/base/icons/src/public/llm'
@ -40,7 +41,7 @@ const ProviderIcon: FC<ProviderIconProps> = ({
<div className={cn('inline-flex items-center gap-2', className)}>
<img
alt='provider-icon'
src={renderI18nObject(provider.icon_small, language)}
src={basePath + renderI18nObject(provider.icon_small, language)}
className='h-6 w-6'
/>
<div className='system-md-semibold text-text-primary'>

View File

@ -14,6 +14,7 @@ import Nav from '../nav'
import type { NavItem } from '../nav/nav-selector'
import { fetchDatasetDetail, fetchDatasets } from '@/service/datasets'
import type { DataSetListResponse } from '@/models/datasets'
import { basePath } from '@/utils/var'
const getKey = (pageIndex: number, previousPageData: DataSetListResponse) => {
if (!pageIndex || previousPageData.has_more)
@ -62,7 +63,7 @@ const DatasetNav = () => {
icon_background: dataset.icon_info.icon_background,
})) as NavItem[]}
createText={t('common.menus.newDataset')}
onCreate={() => router.push('/datasets/create')}
onCreate={() => router.push(`${basePath}/datasets/create`)}
onLoadMore={handleLoadMore}
/>
)

View File

@ -70,7 +70,7 @@ const NavSelector = ({ curNav, navigationItems, createText, isApp, onCreate, onL
<MenuItems
className="
absolute -left-11 right-0 mt-1.5 w-60 max-w-80
origin-top-right divide-y divide-gray-100 rounded-lg bg-white
origin-top-right divide-y divide-divider-regular rounded-lg bg-components-panel-bg-blur
shadow-lg
"
>
@ -78,7 +78,7 @@ const NavSelector = ({ curNav, navigationItems, createText, isApp, onCreate, onL
{
navigationItems.map(nav => (
<MenuItem key={nav.id}>
<div className='flex w-full cursor-pointer items-center truncate rounded-lg px-3 py-[6px] text-[14px] font-normal text-gray-700 hover:bg-gray-100' onClick={() => {
<div className='flex w-full cursor-pointer items-center truncate rounded-lg px-3 py-[6px] text-[14px] font-normal text-text-secondary hover:bg-state-base-hover' onClick={() => {
if (curNav?.id === nav.id)
return
setAppDetail()
@ -119,12 +119,12 @@ const NavSelector = ({ curNav, navigationItems, createText, isApp, onCreate, onL
{!isApp && isCurrentWorkspaceEditor && (
<MenuItem as="div" className='w-full p-1'>
<div onClick={() => onCreate('')} className={cn(
'flex cursor-pointer items-center gap-2 rounded-lg px-3 py-[6px] hover:bg-gray-100',
'flex cursor-pointer items-center gap-2 rounded-lg px-3 py-[6px] hover:bg-state-base-hover ',
)}>
<div className='flex h-6 w-6 shrink-0 items-center justify-center rounded-[6px] border border-[0.5px] border-gray-200 bg-gray-50'>
<RiAddLine className='h-4 w-4 text-gray-500' />
<div className='flex h-6 w-6 shrink-0 items-center justify-center rounded-[6px] border-[0.5px] border-divider-regular bg-background-default'>
<RiAddLine className='h-4 w-4 text-text-primary' />
</div>
<div className='grow text-left text-[14px] font-normal text-gray-700'>{createText}</div>
<div className='grow text-left text-[14px] font-normal text-text-secondary'>{createText}</div>
</div>
</MenuItem>
)}
@ -134,14 +134,14 @@ const NavSelector = ({ curNav, navigationItems, createText, isApp, onCreate, onL
<>
<MenuButton className='w-full p-1'>
<div className={cn(
'flex cursor-pointer items-center gap-2 rounded-lg px-3 py-[6px] hover:bg-gray-100',
open && '!bg-gray-100',
'flex cursor-pointer items-center gap-2 rounded-lg px-3 py-[6px] hover:bg-state-base-hover',
open && '!bg-state-base-hover',
)}>
<div className='flex h-6 w-6 shrink-0 items-center justify-center rounded-[6px] border border-[0.5px] border-gray-200 bg-gray-50'>
<RiAddLine className='h-4 w-4 text-gray-500' />
<div className='flex h-6 w-6 shrink-0 items-center justify-center rounded-[6px] border-[0.5px] border-divider-regular bg-background-default'>
<RiAddLine className='h-4 w-4 text-text-primary' />
</div>
<div className='grow text-left text-[14px] font-normal text-gray-700'>{createText}</div>
<RiArrowRightSLine className='h-3.5 w-3.5 shrink-0 text-gray-500' />
<div className='grow text-left text-[14px] font-normal text-text-secondary'>{createText}</div>
<RiArrowRightSLine className='h-3.5 w-3.5 shrink-0 text-text-primary' />
</div>
</MenuButton>
<Transition
@ -154,21 +154,21 @@ const NavSelector = ({ curNav, navigationItems, createText, isApp, onCreate, onL
leaveTo="transform opacity-0 scale-95"
>
<MenuItems className={cn(
'absolute right-[-198px] top-[3px] z-10 min-w-[200px] rounded-lg border-[0.5px] border-gray-200 bg-white shadow-lg',
'absolute right-[-198px] top-[3px] z-10 min-w-[200px] rounded-lg bg-components-panel-bg-blur shadow-lg',
)}>
<div className='p-1'>
<div className={cn('flex cursor-pointer items-center rounded-lg px-3 py-[6px] font-normal text-gray-700 hover:bg-gray-100')} onClick={() => onCreate('blank')}>
<FilePlus01 className='mr-2 h-4 w-4 shrink-0 text-gray-600' />
<div className={cn('flex cursor-pointer items-center rounded-lg px-3 py-[6px] font-normal text-text-secondary hover:bg-state-base-hover')} onClick={() => onCreate('blank')}>
<FilePlus01 className='mr-2 h-4 w-4 shrink-0 text-text-secondary' />
{t('app.newApp.startFromBlank')}
</div>
<div className={cn('flex cursor-pointer items-center rounded-lg px-3 py-[6px] font-normal text-gray-700 hover:bg-gray-100')} onClick={() => onCreate('template')}>
<FilePlus02 className='mr-2 h-4 w-4 shrink-0 text-gray-600' />
<div className={cn('flex cursor-pointer items-center rounded-lg px-3 py-[6px] font-normal text-text-secondary hover:bg-state-base-hover')} onClick={() => onCreate('template')}>
<FilePlus02 className='mr-2 h-4 w-4 shrink-0 text-text-secondary' />
{t('app.newApp.startFromTemplate')}
</div>
</div>
<div className='border-t border-gray-100 p-1'>
<div className={cn('flex cursor-pointer items-center rounded-lg px-3 py-[6px] font-normal text-gray-700 hover:bg-gray-100')} onClick={() => onCreate('dsl')}>
<FileArrow01 className='mr-2 h-4 w-4 shrink-0 text-gray-600' />
<div className='border-t border-divider-regular p-1'>
<div className={cn('flex cursor-pointer items-center rounded-lg px-3 py-[6px] font-normal text-text-secondary hover:bg-state-base-hover')} onClick={() => onCreate('dsl')}>
<FileArrow01 className='mr-2 h-4 w-4 shrink-0 text-text-secondary' />
{t('app.importDSL')}
</div>
</div>

View File

@ -2,7 +2,7 @@ import {
memo,
useCallback,
} from 'react'
import Link from 'next/link'
import { basePath } from '@/utils/var'
import { useTranslation } from 'react-i18next'
import {
RiAddLine,
@ -54,7 +54,7 @@ const Blocks = ({
>
<div className='flex h-[22px] w-full items-center justify-between pl-3 pr-1 text-xs font-medium text-gray-500'>
{toolWithProvider.label[language]}
<Link className='hidden cursor-pointer items-center group-hover:flex' href={`/tools?category=${toolWithProvider.type}`} target='_blank'>{t('tools.addToolModal.manageInTools')}<ArrowUpRight className='ml-0.5 h-3 w-3' /></Link>
<a className='hidden cursor-pointer items-center group-hover:flex' href={`${basePath}/tools?category=${toolWithProvider.type}`} target='_blank'>{t('tools.addToolModal.manageInTools')}<ArrowUpRight className='ml-0.5 h-3 w-3' /></a>
</div>
{list.map((tool) => {
const labelContent = (() => {

View File

@ -6,7 +6,7 @@ import {
RiCloseLine,
} from '@remixicon/react'
import { AuthHeaderPrefix, AuthType, CollectionType } from '../types'
import Link from 'next/link'
import { basePath } from '@/utils/var'
import type { Collection, CustomCollectionBackend, Tool, WorkflowToolProviderRequest, WorkflowToolProviderResponse } from '../types'
import ToolItem from './tool-item'
import cn from '@/utils/classnames'
@ -279,10 +279,10 @@ const ProviderDetail = ({
variant='primary'
className={cn('my-3 w-[183px] shrink-0')}
>
<Link className='flex items-center' href={`/app/${(customCollection as WorkflowToolProviderResponse).workflow_app_id}/workflow`} rel='noreferrer' target='_blank'>
<a className='flex items-center' href={`${basePath}/app/${(customCollection as WorkflowToolProviderResponse).workflow_app_id}/workflow`} rel='noreferrer' target='_blank'>
<div className='system-sm-medium'>{t('tools.openInStudio')}</div>
<LinkExternal02 className='ml-1 h-4 w-4' />
</Link>
</a>
</Button>
<Button
className={cn('my-3 w-[183px] shrink-0')}

View File

@ -3,7 +3,6 @@ import type { FC } from 'react'
import Editor, { loader } from '@monaco-editor/react'
import React, { useEffect, useMemo, useRef, useState } from 'react'
import Base from '../base'
import { WEB_PREFIX } from '@/config'
import cn from '@/utils/classnames'
import { CodeLanguage } from '@/app/components/workflow/nodes/code/types'
import {
@ -13,9 +12,10 @@ import { Theme } from '@/types/app'
import useTheme from '@/hooks/use-theme'
import './style.css'
import { noop } from 'lodash-es'
import { basePath } from '@/utils/var'
// load file from local instead of cdn https://github.com/suren-atoyan/monaco-react/issues/482
loader.config({ paths: { vs: `${WEB_PREFIX}/vs` } })
loader.config({ paths: { vs: `${basePath}/vs` } })
const CODE_EDITOR_LINE_HEIGHT = 18

View File

@ -50,7 +50,7 @@ const ConstantField: FC<Props> = ({
{schema.type === FormTypeEnum.textNumber && (
<input
type='number'
className='h-8 w-full overflow-hidden rounded-lg bg-gray-100 p-2 text-[13px] font-normal leading-8 text-gray-900 placeholder:text-gray-400 focus:outline-none'
className='h-8 w-full overflow-hidden rounded-lg bg-workflow-block-parma-bg p-2 text-[13px] font-normal leading-8 text-text-secondary placeholder:text-gray-400 focus:outline-none'
value={value}
onChange={handleStaticChange}
readOnly={readonly}

View File

@ -124,11 +124,11 @@ const ConditionItem = ({
)}>
<div className='flex items-center p-1'>
<div className='w-0 grow'>
<div className='inline-flex h-6 items-center rounded-md border-[0.5px] border-components-panel-border-subtle bg-components-badge-white-to-dark pl-1 pr-1.5 shadow-xs'>
<div className='flex h-6 min-w-0 items-center rounded-md border-[0.5px] border-components-panel-border-subtle bg-components-badge-white-to-dark pl-1 pr-1.5 shadow-xs'>
<div className='mr-0.5 p-[1px]'>
<MetadataIcon type={currentMetadata?.type} className='h-3 w-3' />
</div>
<div className='system-xs-medium mr-0.5 text-text-secondary'>{currentMetadata?.name}</div>
<div className='system-xs-medium mr-0.5 min-w-0 flex-1 truncate text-text-secondary'>{currentMetadata?.name}</div>
<div className='system-xs-regular text-text-tertiary'>{currentMetadata?.type}</div>
</div>
</div>