wwf
4 天以前 73210a869048d6468b55717660d0ca558d0c2aab
优化
26个文件已修改
3个文件已添加
405 ■■■■■ 已修改文件
app/(commonLayout)/apps/AppCard.tsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/apps/Apps.tsx 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/apps/NewAppCard.tsx 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/apps/page.tsx 22 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/datasets/Container.tsx 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/datasets/DatasetFooter.tsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app-sidebar/app-info.tsx 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app-sidebar/index.tsx 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/app-publisher/index.tsx 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config-prompt/simple-prompt-input.tsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config/agent/create-workFlow.tsx 85 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/configuration/config/index.tsx 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/app/create-app-modal/index.tsx 90 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/app-icon/index.tsx 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/base/features/new-feature-panel/feature-bar.tsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/explore/create-app-modal/index.tsx 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/index.tsx 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/header/nav/index.tsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/components/swr-initor.tsx 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/signin/_header.tsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/signin/layout.tsx 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hans/app-debug.ts 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hans/app.ts 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hans/login.ts 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
i18n/zh-Hant/app-debug.ts 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
models/common.ts 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/avatar/agent.png 补丁 | 查看 | 原始文档 | blame | 历史
public/avatar/workflow.png 补丁 | 查看 | 原始文档 | blame | 历史
service/common.ts 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
app/(commonLayout)/apps/AppCard.tsx
@@ -30,7 +30,7 @@
import DSLExportConfirmModal from '@/app/components/workflow/dsl-export-confirm-modal'
import { fetchWorkflowDraft } from '@/service/workflow'
import { fetchInstalledAppList } from '@/service/explore'
import { AppTypeIcon } from '@/app/components/app/type-selector'
// import { AppTypeIcon } from '@/app/components/app/type-selector'
export type AppCardProps = {
  app: App
@@ -285,9 +285,9 @@
              iconType={app.icon_type}
              icon={app.icon}
              background={app.icon_background}
              imageUrl={app.icon_url}
              imageUrl={app.mode === 'agent-chat' ? '/avatar/agent.png' : '/avatar/workflow.png'}
            />
            <AppTypeIcon type={app.mode} wrapperClassName='absolute -bottom-0.5 -right-0.5 w-4 h-4 shadow-sm' className='w-3 h-3' />
            {/* <AppTypeIcon type={app.mode} wrapperClassName='absolute -bottom-0.5 -right-0.5 w-4 h-4 shadow-sm' className='w-3 h-3' /> */}
          </div>
          <div className='grow w-0 py-[1px]'>
            <div className='flex items-center text-sm leading-5 font-semibold text-text-secondary'>
app/(commonLayout)/apps/Apps.tsx
@@ -7,9 +7,6 @@
import { useDebounceFn } from 'ahooks'
import {
  RiApps2Line,
  RiExchange2Line,
  RiMessage3Line,
  RiRobot3Line,
} from '@remixicon/react'
import AppCard from './AppCard'
import NewAppCard from './NewAppCard'
@@ -25,7 +22,7 @@
import { useStore as useTagStore } from '@/app/components/base/tag-management/store'
import TagManagementModal from '@/app/components/base/tag-management'
import TagFilter from '@/app/components/base/tag-management/filter'
import CheckboxWithLabel from '@/app/components/datasets/create/website/base/checkbox-with-label'
// import CheckboxWithLabel from '@/app/components/datasets/create/website/base/checkbox-with-label'
const getKey = (
  pageIndex: number,
@@ -36,7 +33,7 @@
  keywords: string,
) => {
  if (!pageIndex || previousPageData.has_more) {
    const params: any = { url: 'apps', params: { page: pageIndex + 1, limit: 30, name: keywords, is_created_by_me: isCreatedByMe } }
    const params: any = { url: 'apps', params: { page: pageIndex + 1, limit: 30, name: keywords, is_created_by_me: true } }
    if (activeTab !== 'all')
      params.params.mode = activeTab
@@ -79,9 +76,9 @@
  const anchorRef = useRef<HTMLDivElement>(null)
  const options = [
    { value: 'all', text: t('app.types.all'), icon: <RiApps2Line className='w-[14px] h-[14px] mr-1' /> },
    { value: 'chat', text: t('app.types.chatbot'), icon: <RiMessage3Line className='w-[14px] h-[14px] mr-1' /> },
    { value: 'agent-chat', text: t('app.types.agent'), icon: <RiRobot3Line className='w-[14px] h-[14px] mr-1' /> },
    { value: 'workflow', text: t('app.types.workflow'), icon: <RiExchange2Line className='w-[14px] h-[14px] mr-1' /> },
    // { value: 'chat', text: t('app.types.chatbot'), icon: <RiMessage3Line className='w-[14px] h-[14px] mr-1' /> },
    // { value: 'agent-chat', text: t('app.types.agent'), icon: <RiRobot3Line className='w-[14px] h-[14px] mr-1' /> },
    // { value: 'workflow', text: t('app.types.workflow'), icon: <RiExchange2Line className='w-[14px] h-[14px] mr-1' /> },
  ]
  useEffect(() => {
@@ -135,12 +132,12 @@
          options={options}
        />
        <div className='flex items-center gap-2'>
          <CheckboxWithLabel
          {/* <CheckboxWithLabel
            className='mr-2'
            label={t('app.showMyCreatedAppsOnly')}
            isChecked={isCreatedByMe}
            onChange={() => setIsCreatedByMe(!isCreatedByMe)}
          />
          /> */}
          <TagFilter type='app' value={tagFilterValue} onChange={handleTagsChange} />
          <Input
            showLeftIcon
app/(commonLayout)/apps/NewAppCard.tsx
@@ -10,7 +10,7 @@
import CreateAppModal from '@/app/components/app/create-app-modal'
import CreateFromDSLModal, { CreateFromDSLModalTab } from '@/app/components/app/create-from-dsl-modal'
import { useProviderContext } from '@/context/provider-context'
import { FileArrow01, FilePlus01, FilePlus02 } from '@/app/components/base/icons/src/vender/line/files'
import { FilePlus01 } from '@/app/components/base/icons/src/vender/line/files'
import cn from '@/utils/classnames'
export type CreateAppCardProps = {
@@ -45,9 +45,9 @@
        <div className='px-6 pt-2 pb-1 text-xs font-medium leading-[18px] text-text-tertiary'>{t('app.createApp')}</div>
        <button className='w-full flex items-center mb-1 px-6 py-[7px] rounded-lg text-[13px] font-medium leading-[18px] text-text-tertiary cursor-pointer hover:text-text-secondary hover:bg-state-base-hover' onClick={() => setShowNewAppModal(true)}>
          <FilePlus01 className='shrink-0 mr-2 w-4 h-4' />
          {t('app.newApp.startFromBlank')}
          创建智能体
        </button>
        <button className='w-full flex items-center px-6 py-[7px] rounded-lg text-[13px] font-medium leading-[18px] text-text-tertiary cursor-pointer hover:text-text-secondary hover:bg-state-base-hover' onClick={() => setShowNewAppTemplateDialog(true)}>
        {/* <button className='w-full flex items-center px-6 py-[7px] rounded-lg text-[13px] font-medium leading-[18px] text-text-tertiary cursor-pointer hover:text-text-secondary hover:bg-state-base-hover' onClick={() => setShowNewAppTemplateDialog(true)}>
          <FilePlus02 className='shrink-0 mr-2 w-4 h-4' />
          {t('app.newApp.startFromTemplate')}
        </button>
@@ -56,7 +56,7 @@
          className='w-full flex items-center px-6 py-[7px] rounded-lg text-[13px] font-medium leading-[18px] text-text-tertiary cursor-pointer hover:text-text-secondary hover:bg-state-base-hover'>
          <FileArrow01 className='shrink-0 mr-2 w-4 h-4' />
          {t('app.importDSL')}
        </button>
        </button> */}
      </div>
      <CreateAppModal
app/(commonLayout)/apps/page.tsx
@@ -1,21 +1,21 @@
'use client'
import { useContextSelector } from 'use-context-selector'
import { useTranslation } from 'react-i18next'
import { RiDiscordFill, RiGithubFill } from '@remixicon/react'
import Link from 'next/link'
import style from '../list.module.css'
// import { useContextSelector } from 'use-context-selector'
// import { useTranslation } from 'react-i18next'
// import { RiDiscordFill, RiGithubFill } from '@remixicon/react'
// import Link from 'next/link'
// import style from '../list.module.css'
import Apps from './Apps'
import AppContext from '@/context/app-context'
import { LicenseStatus } from '@/types/feature'
// import AppContext from '@/context/app-context'
// import { LicenseStatus } from '@/types/feature'
const AppList = () => {
  const { t } = useTranslation()
  const systemFeatures = useContextSelector(AppContext, v => v.systemFeatures)
  // const { t } = useTranslation()
  // const systemFeatures = useContextSelector(AppContext, v => v.systemFeatures)
  return (
    <div className='relative flex flex-col overflow-y-auto bg-background-body shrink-0 h-0 grow'>
      <Apps />
      {systemFeatures.license.status === LicenseStatus.NONE && <footer className='px-12 py-6 grow-0 shrink-0'>
      {/* {systemFeatures.license.status === LicenseStatus.NONE && <footer className='px-12 py-6 grow-0 shrink-0'>
        <h3 className='text-xl font-semibold leading-tight text-gradient'>{t('app.join')}</h3>
        <p className='mt-1 system-sm-regular text-text-tertiary'>{t('app.communityIntro')}</p>
        <div className='flex items-center gap-2 mt-3'>
@@ -26,7 +26,7 @@
            <RiDiscordFill className='w-5 h-5 text-text-tertiary' />
          </Link>
        </div>
      </footer>}
      </footer>} */}
    </div >
  )
}
app/(commonLayout)/datasets/Container.tsx
@@ -41,7 +41,7 @@
  const options = useMemo(() => {
    return [
      { value: 'dataset', text: t('dataset.datasets') },
      ...(currentWorkspace.role === 'dataset_operator' ? [] : [{ value: 'api', text: t('dataset.datasetsApi') }]),
      // ...(currentWorkspace.role === 'dataset_operator' ? [] : [{ value: 'api', text: t('dataset.datasetsApi') }]),
    ]
  }, [currentWorkspace.role, t])
@@ -109,13 +109,13 @@
              onClear={() => handleKeywordsChange('')}
            />
            <div className="w-[1px] h-4 bg-divider-regular" />
            <Button
            {/* <Button
              className='gap-0.5 shadows-shadow-xs'
              onClick={() => setShowExternalApiPanel(true)}
            >
              <ApiConnectionMod className='w-4 h-4 text-components-button-secondary-text' />
              <div className='flex px-0.5 justify-center items-center gap-1 text-components-button-secondary-text system-sm-medium'>{t('dataset.externalAPIPanelTitle')}</div>
            </Button>
            </Button> */}
          </div>
        )}
        {activeTab === 'api' && data && <ApiServer apiBaseUrl={data.api_base_url || ''} />}
app/(commonLayout)/datasets/DatasetFooter.tsx
@@ -7,11 +7,11 @@
  return (
    <footer className='px-12 py-6 grow-0 shrink-0'>
      <h3 className='text-xl font-semibold leading-tight text-gradient'>{t('dataset.didYouKnow')}</h3>
      {/* <h3 className='text-xl font-semibold leading-tight text-gradient'>{t('dataset.didYouKnow')}</h3>
      <p className='mt-1 text-sm font-normal leading-tight text-gray-700'>
        {t('dataset.intro1')}<span className='inline-flex items-center gap-1 text-blue-600'>{t('dataset.intro2')}</span>{t('dataset.intro3')}<br />
        {t('dataset.intro4')}<span className='inline-flex items-center gap-1 text-blue-600'>{t('dataset.intro5')}</span>{t('dataset.intro6')}
      </p>
      </p> */}
    </footer>
  )
}
app/components/app-sidebar/app-info.tsx
@@ -191,10 +191,6 @@
    >
      <div className='relative'>
        <PortalToFollowElemTrigger
          onClick={() => {
            if (isCurrentWorkspaceEditor)
              setOpen(v => !v)
          }}
          className='block'
        >
          <div className={cn('flex p-1 rounded-lg', open && 'bg-gray-100', isCurrentWorkspaceEditor && 'hover:bg-gray-100 cursor-pointer')}>
@@ -204,28 +200,8 @@
                iconType={appDetail.icon_type}
                icon={appDetail.icon}
                background={appDetail.icon_background}
                imageUrl={appDetail.icon_url}
                imageUrl={appDetail.mode === 'agent-chat' ? '/avatar/agent.png' : '/avatar/workflow.png' }
              />
              <span className={cn(
                'absolute bottom-[-3px] right-[-3px] w-4 h-4 p-0.5 bg-white rounded border-[0.5px] border-[rgba(0,0,0,0.02)] shadow-sm',
                !expand && '!w-3.5 !h-3.5 !bottom-[-2px] !right-[-2px]',
              )}>
                {appDetail.mode === 'advanced-chat' && (
                  <ChatBot className={cn('w-3 h-3 text-[#1570EF]', !expand && '!w-2.5 !h-2.5')} />
                )}
                {appDetail.mode === 'agent-chat' && (
                  <CuteRobot className={cn('w-3 h-3 text-indigo-600', !expand && '!w-2.5 !h-2.5')} />
                )}
                {appDetail.mode === 'chat' && (
                  <ChatBot className={cn('w-3 h-3 text-[#1570EF]', !expand && '!w-2.5 !h-2.5')} />
                )}
                {appDetail.mode === 'completion' && (
                  <AiText className={cn('w-3 h-3 text-[#0E9384]', !expand && '!w-2.5 !h-2.5')} />
                )}
                {appDetail.mode === 'workflow' && (
                  <Route className={cn('w-3 h-3 text-[#f79009]', !expand && '!w-2.5 !h-2.5')} />
                )}
              </span>
            </div>
            {expand && (
              <div className="grow w-0">
app/components/app-sidebar/index.tsx
@@ -95,7 +95,7 @@
      >
        {navigation.map((item, index) => {
          return (
            <NavLink key={index} mode={appSidebarExpand} iconMap={{ selected: item.selectedIcon, normal: item.icon }} name={item.name} href={item.href} />
            item.name === '编排' && <NavLink key={index} mode={appSidebarExpand} iconMap={{ selected: item.selectedIcon, normal: item.icon }} name={item.name} href={item.href} />
          )
        })}
      </nav>
app/components/app/app-publisher/index.tsx
@@ -76,6 +76,8 @@
  const handlePublish = async (modelAndParameter?: ModelAndParameter) => {
    try {
      const messageData = { agentInfo: appDetail?.model_config }
      window.parent.postMessage(messageData, '*')
      await onPublish?.(modelAndParameter)
      setPublished(true)
    }
app/components/app/configuration/config-prompt/simple-prompt-input.tsx
@@ -177,11 +177,11 @@
                />
              )}
            </div>
            <div className='flex items-center'>
            {/* <div className='flex items-center'>
              {!readonly && !isMobile && (
                <AutomaticBtn onClick={showAutomaticTrue} />
              )}
            </div>
            </div> */}
          </div>
        )}
app/components/app/configuration/config/agent/create-workFlow.tsx
New file
@@ -0,0 +1,85 @@
'use client'
import type { FC } from 'react'
import React, { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
import produce from 'immer'
import { useFormattingChangedDispatcher } from '../../debug/hooks'
import CreateAppModal from '@/app/components/app/create-app-modal'
import Panel from '@/app/components/app/configuration/base/feature-panel'
import OperationBtn from '@/app/components/app/configuration/base/operation-btn'
import ConfigContext from '@/context/debug-configuration'
import type { AgentTool } from '@/types/app'
import { type Collection } from '@/app/components/tools/types'
import { useProviderContext } from '@/context/provider-context'
type AgentToolWithMoreInfo = AgentTool & { icon: any; collection?: Collection } | null
const CreateWorkFlow: FC = () => {
  const { t } = useTranslation()
  const [isShowChooseTool, setIsShowChooseTool] = useState(false)
  const [showNewAppTemplateDialog, setShowNewAppTemplateDialog] = useState(false)
  const { modelConfig, setModelConfig, collectionList } = useContext(ConfigContext)
  const formattingChangedDispatcher = useFormattingChangedDispatcher()
  const [showNewAppModal, setShowNewAppModal] = useState(false)
  const { onPlanInfoChanged } = useProviderContext()
  const [currentTool, setCurrentTool] = useState<AgentToolWithMoreInfo>(null)
  const [isShowSettingTool, setIsShowSettingTool] = useState(false)
  const tools = (modelConfig?.agentConfig?.tools as AgentTool[] || []).map((item) => {
    const collection = collectionList.find(collection => collection.id === item.provider_id && collection.type === item.provider_type)
    const icon = collection?.icon
    return {
      ...item,
      icon,
      collection,
    }
  })
  const handleToolSettingChange = (value: Record<string, any>) => {
    const newModelConfig = produce(modelConfig, (draft) => {
      const tool = (draft.agentConfig.tools).find((item: any) => item.provider_id === currentTool?.collection?.id && item.tool_name === currentTool?.tool_name)
      if (tool)
        (tool as AgentTool).tool_parameters = value
    })
    setModelConfig(newModelConfig)
    setIsShowSettingTool(false)
    formattingChangedDispatcher()
  }
  return (
    <>
      <Panel
        className="mt-2"
        noBodySpacing={tools.length === 0}
        headerIcon={
          <span> - </span>
        }
        title={
          <div className='flex items-center'>
            <div className='mr-1'>创建工作流</div>
          </div>
        }
        headerRight={
          <div className='flex items-center'>
            <OperationBtn type="add" actionName="创建" onClick={() => setShowNewAppModal(true)} />
          </div>
        }
      >
        <div className='grid gap-1 grid-cols-1 2xl:grid-cols-2 items-center flex-wrap justify-between'></div>
      </Panel >
      <CreateAppModal
        show={showNewAppModal}
        onClose={() => setShowNewAppModal(false)}
        isWorkFlow={true}
        onSuccess={() => {
          onPlanInfoChanged()
        }}
        onCreateFromTemplate={() => {
          setShowNewAppTemplateDialog(true)
          setShowNewAppModal(false)
        }}
      />
    </>
  )
}
export default React.memo(CreateWorkFlow)
app/components/app/configuration/config/index.tsx
@@ -9,6 +9,7 @@
import ConfigVision from '../config-vision'
import ConfigDocument from './config-document'
import AgentTools from './agent/agent-tools'
import CreateWorkflow from './agent/create-workFlow'
import ConfigContext from '@/context/debug-configuration'
import ConfigPrompt from '@/app/components/app/configuration/config-prompt'
import ConfigVar from '@/app/components/app/configuration/config-var'
@@ -81,6 +82,10 @@
          <AgentTools />
        )}
        {isAgent && (
          <CreateWorkflow />
        )}
        <ConfigVision />
        <ConfigDocument />
app/components/app/create-app-modal/index.tsx
@@ -5,10 +5,10 @@
import { useRouter } from 'next/navigation'
import { useContext, useContextSelector } from 'use-context-selector'
import { RiArrowRightLine, RiCommandLine, RiCornerDownLeftLine, RiExchange2Fill } from '@remixicon/react'
import Link from 'next/link'
import { RiCommandLine, RiCornerDownLeftLine, RiExchange2Fill } from '@remixicon/react'
import { useDebounceFn, useKeyPress } from 'ahooks'
import Image from 'next/image'
import AppIcon from '../../base/app-icon'
import AppIconPicker from '../../base/app-icon-picker'
import type { AppIconSelection } from '../../base/app-icon-picker'
import Button from '@/app/components/base/button'
@@ -21,9 +21,8 @@
import { createApp } from '@/service/apps'
import Input from '@/app/components/base/input'
import Textarea from '@/app/components/base/textarea'
import AppIcon from '@/app/components/base/app-icon'
import AppsFull from '@/app/components/billing/apps-full-in-dialog'
import { BubbleTextMod, ChatBot, ListSparkle, Logic } from '@/app/components/base/icons/src/vender/solid/communication'
import { Logic } from '@/app/components/base/icons/src/vender/solid/communication'
import { NEED_REFRESH_APP_LIST_KEY } from '@/config'
import { getRedirection } from '@/utils/app-redirection'
import FullScreenModal from '@/app/components/base/fullscreen-modal'
@@ -32,9 +31,10 @@
  onSuccess: () => void
  onClose: () => void
  onCreateFromTemplate?: () => void
  isWorkFlow?: boolean
}
function CreateApp({ onClose, onSuccess, onCreateFromTemplate }: CreateAppProps) {
function CreateApp({ onClose, onSuccess, onCreateFromTemplate, isWorkFlow }: CreateAppProps) {
  const { t } = useTranslation()
  const { push } = useRouter()
  const { notify } = useContext(ToastContext)
@@ -71,7 +71,7 @@
        icon_type: appIcon.type,
        icon: appIcon.type === 'emoji' ? appIcon.icon : appIcon.fileId,
        icon_background: appIcon.type === 'emoji' ? appIcon.background : undefined,
        mode: appMode,
        mode: isWorkFlow ? 'workflow' : 'agent-chat',
      })
      notify({ type: 'success', message: t('app.newApp.appCreated') })
      onSuccess()
@@ -94,22 +94,22 @@
  })
  return <>
    <div className='flex justify-center h-full overflow-y-auto overflow-x-hidden'>
      <div className='flex-1 shrink-0 flex justify-end'>
      <div className='flex-1 shrink-0 flex justify-center'>
        <div className='px-10'>
          <div className='w-full h-6 2xl:h-[139px]' />
          <div className='w-full h-6 2xl:h-[20px]' />
          <div className='pt-1 pb-6'>
            <span className='title-2xl-semi-bold text-text-primary'>{t('app.newApp.startFromBlank')}</span>
            <span className='title-2xl-semi-bold text-text-primary'>{ isWorkFlow ? '创建工作流' : '创建智能体' }</span>
          </div>
          <div className='leading-6 mb-2'>
          {!isWorkFlow && <div className='leading-6 mb-2'>
            <span className='system-sm-semibold text-text-secondary'>{t('app.newApp.chooseAppType')}</span>
          </div>
          </div>}
          <div className='flex flex-col w-[660px] gap-4'>
            <div>
              <div className='mb-2'>
            {!isWorkFlow && <div>
              {/* <div className='mb-2'>
                <span className='system-2xs-medium-uppercase text-text-tertiary'>{t('app.newApp.forBeginners')}</span>
              </div>
              </div> */}
              <div className='flex flex-row gap-2'>
                <AppTypeCard
                {/* <AppTypeCard
                  active={appMode === 'chat'}
                  title={t('app.types.chatbot')}
                  description={t('app.newApp.chatbotShortDescription')}
@@ -118,7 +118,7 @@
                  </div>}
                  onClick={() => {
                    setAppMode('chat')
                  }} />
                  }} /> */}
                <AppTypeCard
                  active={appMode === 'agent-chat'}
                  title={t('app.types.agent')}
@@ -129,7 +129,7 @@
                  onClick={() => {
                    setAppMode('agent-chat')
                  }} />
                <AppTypeCard
                {/* <AppTypeCard
                  active={appMode === 'completion'}
                  title={t('app.newApp.completeApp')}
                  description={t('app.newApp.completionShortDescription')}
@@ -138,15 +138,15 @@
                  </div>}
                  onClick={() => {
                    setAppMode('completion')
                  }} />
                  }} /> */}
              </div>
            </div>
            </div>}
            <div>
              <div className='mb-2'>
              {/* <div className='mb-2'>
                <span className='system-2xs-medium-uppercase text-text-tertiary'>{t('app.newApp.forAdvanced')}</span>
              </div>
              </div> */}
              <div className='flex flex-row gap-2'>
                <AppTypeCard
                {/* <AppTypeCard
                  beta
                  active={appMode === 'advanced-chat'}
                  title={t('app.types.advanced')}
@@ -156,8 +156,8 @@
                  </div>}
                  onClick={() => {
                    setAppMode('advanced-chat')
                  }} />
                <AppTypeCard
                  }} /> */}
                {/* <AppTypeCard
                  beta
                  active={appMode === 'workflow'}
                  title={t('app.types.workflow')}
@@ -167,14 +167,14 @@
                  </div>}
                  onClick={() => {
                    setAppMode('workflow')
                  }} />
                  }} /> */}
              </div>
            </div>
            <Divider style={{ margin: 0 }} />
            <div className='flex space-x-3 items-center'>
              <div className='flex-1'>
                <div className='h-6 flex items-center mb-1'>
                  <label className='system-sm-semibold text-text-secondary'>{t('app.newApp.captionName')}</label>
                  <label className='system-sm-semibold text-text-secondary'>应用名称</label>
                </div>
                <Input
                  value={name}
@@ -182,14 +182,14 @@
                  placeholder={t('app.newApp.appNamePlaceholder') || ''}
                />
              </div>
              <AppIcon
              {/* <AppIcon
                iconType={appIcon.type}
                icon={appIcon.type === 'emoji' ? appIcon.icon : appIcon.fileId}
                background={appIcon.type === 'emoji' ? appIcon.background : undefined}
                imageUrl={appIcon.type === 'image' ? appIcon.url : undefined}
                size='xxl' className='cursor-pointer rounded-2xl'
                onClick={() => { setShowAppIconPicker(true) }}
              />
              /> */}
              {showAppIconPicker && <AppIconPicker
                onSelect={(payload) => {
                  setAppIcon(payload)
@@ -214,12 +214,12 @@
            </div>
          </div>
          <div className='pt-5 pb-10 flex justify-between items-center'>
            <div className='flex gap-1 items-center system-xs-regular text-text-tertiary cursor-pointer' onClick={onCreateFromTemplate}>
            {/* <div className='flex gap-1 items-center system-xs-regular text-text-tertiary cursor-pointer' onClick={onCreateFromTemplate}>
              <span>{t('app.newApp.noIdeaTip')}</span>
              <div className='p-[1px]'>
                <RiArrowRightLine className='w-3.5 h-3.5' />
              </div>
            </div>
            </div> */}
            <div className='flex gap-2'>
              <Button onClick={onClose}>{t('app.newApp.Cancel')}</Button>
              <Button disabled={isAppsFull || !name} className='gap-1' variant="primary" onClick={handleCreateApp}>
@@ -231,22 +231,6 @@
              </Button>
            </div>
          </div>
        </div>
      </div>
      <div className='flex-1 shrink h-full flex justify-start relative overflow-hidden'>
        <div className='h-6 2xl:h-[139px] absolute left-0 top-0 right-0 border-b border-b-divider-subtle'></div>
        <div className='max-w-[760px] border-x border-x-divider-subtle'>
          <div className='h-6 2xl:h-[139px]' />
          <AppPreview mode={appMode} />
          <div className='absolute left-0 right-0 border-b border-b-divider-subtle'></div>
          <div className='w-[664px] h-[448px] flex items-center justify-center' style={{ background: 'repeating-linear-gradient(135deg, transparent, transparent 2px, rgba(16,24,40,0.04) 4px,transparent 3px, transparent 6px)' }}>
            <AppScreenShot show={appMode === 'chat'} mode='chat' />
            <AppScreenShot show={appMode === 'advanced-chat'} mode='advanced-chat' />
            <AppScreenShot show={appMode === 'agent-chat'} mode='agent-chat' />
            <AppScreenShot show={appMode === 'completion'} mode='completion' />
            <AppScreenShot show={appMode === 'workflow'} mode='workflow' />
          </div>
          <div className='absolute left-0 right-0 border-b border-b-divider-subtle'></div>
        </div>
      </div>
    </div>
@@ -262,7 +246,7 @@
type CreateAppDialogProps = CreateAppProps & {
  show: boolean
}
const CreateAppModal = ({ show, onClose, onSuccess, onCreateFromTemplate }: CreateAppDialogProps) => {
const CreateAppModal = ({ show, onClose, onSuccess, onCreateFromTemplate, isWorkFlow }: CreateAppDialogProps) => {
  return (
    <FullScreenModal
      overflowVisible
@@ -270,7 +254,7 @@
      open={show}
      onClose={onClose}
    >
      <CreateApp onClose={onClose} onSuccess={onSuccess} onCreateFromTemplate={onCreateFromTemplate} />
      <CreateApp isWorkFlow={isWorkFlow} onClose={onClose} onSuccess={onSuccess} onCreateFromTemplate={onCreateFromTemplate} />
    </FullScreenModal>
  )
}
@@ -300,7 +284,9 @@
    {beta && <div className='px-[5px] py-[3px]
      rounded-[5px] min-w-[18px] absolute top-3 right-3
      border border-divider-deep system-2xs-medium-uppercase text-text-tertiary'>{t('common.menus.status')}</div>}
    {icon}
    <AppIcon
      imageUrl='/avatar/agent.png'
    />
    <div className='system-sm-semibold text-text-secondary mt-2 mb-0.5'>{title}</div>
    <div className='system-xs-regular text-text-tertiary'>{description}</div>
  </div>
@@ -335,13 +321,13 @@
      link: 'https://docs.dify.ai/guides/workflow',
    },
  }
  const previewInfo = modeToPreviewInfoMap[mode]
  // const previewInfo = modeToPreviewInfoMap[mode]
  return <div className='px-8 py-4'>
    <h4 className='system-sm-semibold-uppercase text-text-secondary'>{previewInfo.title}</h4>
    {/* <h4 className='system-sm-semibold-uppercase text-text-secondary'>{previewInfo.title}</h4>
    <div className='mt-1 system-xs-regular text-text-tertiary max-w-96 min-h-8'>
      <span>{previewInfo.description}</span>
      {previewInfo.link && <Link target='_blank' href={previewInfo.link} className='text-text-accent ml-1'>{t('app.newApp.learnMore')}</Link>}
    </div>
    </div> */}
  </div>
}
app/components/base/app-icon/index.tsx
@@ -45,7 +45,6 @@
const AppIcon: FC<AppIconProps> = ({
  size = 'medium',
  rounded = false,
  iconType,
  icon,
  background,
  imageUrl,
@@ -53,7 +52,7 @@
  innerIcon,
  onClick,
}) => {
  const isValidImageIcon = iconType === 'image' && imageUrl
  const isValidImageIcon = true
  return <span
    className={classNames(appIconVariants({ size, rounded }), className)}
@@ -62,7 +61,7 @@
  >
    {isValidImageIcon
      // eslint-disable-next-line @next/next/no-img-element
      ? <img src={imageUrl} className="w-full h-full" alt="app icon" />
      ? <img src={imageUrl || ''} className="w-full h-full" alt="app icon" />
      : (innerIcon || ((icon && icon !== '') ? <em-emoji id={icon} /> : <em-emoji id='🤖' />))
    }
  </span>
app/components/base/features/new-feature-panel/feature-bar.tsx
@@ -37,7 +37,7 @@
  return (
    <div className='-translate-y-2 m-1 mt-0 px-2.5 py-2 pt-4 bg-util-colors-indigo-indigo-50 rounded-b-[10px] border-l border-b border-r border-components-panel-border-subtle'>
      {noFeatureEnabled && (
      {/* {noFeatureEnabled && (
        <div className='flex items-end gap-1 cursor-pointer' onClick={() => onFeatureBarClick?.(true)}>
          <RiApps2AddLine className='w-3.5 h-3.5 text-text-accent' />
          <div className='text-text-accent body-xs-medium'>{t('appDebug.feature.bar.empty')}</div>
@@ -137,7 +137,7 @@
            <RiArrowRightLine className='w-3.5 h-3.5 text-text-accent' />
          </Button>
        </div>
      )}
      )} */}
    </div>
  )
}
app/components/explore/create-app-modal/index.tsx
@@ -9,7 +9,7 @@
import Textarea from '@/app/components/base/textarea'
import Switch from '@/app/components/base/switch'
import Toast from '@/app/components/base/toast'
import AppIcon from '@/app/components/base/app-icon'
// import AppIcon from '@/app/components/base/app-icon'
import { useProviderContext } from '@/context/provider-context'
import AppsFull from '@/app/components/billing/apps-full-in-dialog'
import type { AppIconType } from '@/types/app'
@@ -100,9 +100,9 @@
        <div className='mb-9'>
          {/* icon & name */}
          <div className='pt-2'>
            <div className='py-2 text-sm font-medium leading-[20px] text-gray-900'>{t('app.newApp.captionName')}</div>
            <div className='py-2 text-sm font-medium leading-[20px] text-gray-900'>应用名称</div>
            <div className='flex items-center justify-between space-x-2'>
              <AppIcon
              {/* <AppIcon
                size='large'
                onClick={() => { setShowAppIconPicker(true) }}
                className='cursor-pointer'
@@ -110,7 +110,7 @@
                icon={appIcon.type === 'image' ? appIcon.fileId : appIcon.icon}
                background={appIcon.type === 'image' ? undefined : appIcon.background}
                imageUrl={appIcon.type === 'image' ? appIcon.url : undefined}
              />
              /> */}
              <Input
                value={name}
                onChange={e => setName(e.target.value)}
@@ -130,7 +130,7 @@
            />
          </div>
          {/* answer icon */}
          {isEditModal && (appMode === 'chat' || appMode === 'advanced-chat' || appMode === 'agent-chat') && (
          {/* {isEditModal && (appMode === 'chat' || appMode === 'advanced-chat' || appMode === 'agent-chat') && (
            <div className='pt-2'>
              <div className='flex justify-between items-center'>
                <div className='py-2 text-sm font-medium leading-[20px] text-gray-900'>{t('app.answerIcon.title')}</div>
@@ -141,7 +141,7 @@
              </div>
              <p className='body-xs-regular text-gray-500'>{t('app.answerIcon.descriptionInExplore')}</p>
            </div>
          )}
          )} */}
          {!isEditModal && isAppsFull && <AppsFull loc='app-explore-create' />}
        </div>
        <div className='flex flex-row-reverse'>
app/components/header/index.tsx
@@ -52,46 +52,46 @@
  return (
    <div className='flex flex-1 items-center justify-between px-4 bg-background-body'>
      <div className='flex items-center'>
        {isMobile && <div
        {/* {isMobile && <div
          className='flex items-center justify-center h-8 w-8 cursor-pointer'
          onClick={toggle}
        >
          <Bars3Icon className="h-4 w-4 text-gray-500" />
        </div>}
        </div>} */}
        {!isMobile && <>
          <Link href="/apps" className='flex items-center mr-4'>
          {/* <Link href="/apps" className='flex items-center mr-4'>
            <LogoSite className='object-contain' />
          </Link>
          {systemFeatures.license.status === LicenseStatus.NONE && <GithubStar />}
          </Link> */}
          {/* {systemFeatures.license.status === LicenseStatus.NONE && <GithubStar />} */}
        </>}
      </div>
      {isMobile && (
      {/* {isMobile && (
        <div className='flex'>
          <Link href="/apps" className='flex items-center mr-4'>
            <LogoSite />
          </Link>
          {systemFeatures.license.status === LicenseStatus.NONE && <GithubStar />}
        </div>
      )}
      )} */}
      {!isMobile && (
        <div className='flex items-center'>
          {!isCurrentWorkspaceDatasetOperator && <ExploreNav className={navClassName} />}
          {/* {!isCurrentWorkspaceDatasetOperator && <ExploreNav className={navClassName} />} */}
          {!isCurrentWorkspaceDatasetOperator && <AppNav />}
          {(isCurrentWorkspaceEditor || isCurrentWorkspaceDatasetOperator) && <DatasetNav />}
          {!isCurrentWorkspaceDatasetOperator && <ToolsNav className={navClassName} />}
          {/* {!isCurrentWorkspaceDatasetOperator && <ToolsNav className={navClassName} />} */}
        </div>
      )}
      <div className='flex items-center flex-shrink-0'>
        <LicenseNav />
        <EnvNav />
        {enableBilling && (
        {/* <EnvNav /> */}
        {/* {enableBilling && (
          <div className='mr-3 select-none'>
            <HeaderBillingBtn onClick={handlePlanClick} />
          </div>
        )}
        <WorkspaceProvider>
        )} */}
        {/* <WorkspaceProvider>
          <AccountDropdown isMobile={isMobile} />
        </WorkspaceProvider>
        </WorkspaceProvider> */}
      </div>
      {(isMobile && isShowNavMenu) && (
        <div className='w-full flex flex-col p-2 gap-y-1'>
app/components/header/nav/index.tsx
@@ -65,7 +65,7 @@
          {text}
        </div>
      </Link>
      {
      {/* {
        curNav && isActivated && (
          <>
            <div className='font-light text-gray-300 '>/</div>
@@ -79,7 +79,7 @@
            />
          </>
        )
      }
      } */}
    </div>
  )
}
app/components/swr-initor.tsx
@@ -4,7 +4,8 @@
import { useCallback, useEffect, useState } from 'react'
import type { ReactNode } from 'react'
import { usePathname, useRouter, useSearchParams } from 'next/navigation'
import { fetchSetupStatus } from '@/service/common'
import { fetchSetupStatus, regAndLogin } from '@/service/common'
import type { RegAndLoginResponse } from '@/models/common'
type SwrInitorProps = {
  children: ReactNode
@@ -16,6 +17,7 @@
  const searchParams = useSearchParams()
  const consoleToken = decodeURIComponent(searchParams.get('access_token') || '')
  const refreshToken = decodeURIComponent(searchParams.get('refresh_token') || '')
  const userId = decodeURIComponent(searchParams.get('userId') || '')
  const consoleTokenFromLocalStorage = localStorage?.getItem('console_token')
  const refreshTokenFromLocalStorage = localStorage?.getItem('refresh_token')
  const pathname = usePathname()
@@ -42,22 +44,33 @@
  useEffect(() => {
    (async () => {
      try {
        const isFinished = await isSetupFinished()
        if (!isFinished) {
          router.replace('/install')
          return
        let currentUserId = ''
        if (userId) {
          currentUserId = userId
          localStorage.setItem('userId', userId)
        }
        if (!((consoleToken && refreshToken) || (consoleTokenFromLocalStorage && refreshTokenFromLocalStorage))) {
          router.replace('/signin')
          return
        else {
          currentUserId = localStorage.getItem('userId') || ''
        }
        if (searchParams.has('access_token') || searchParams.has('refresh_token')) {
          consoleToken && localStorage.setItem('console_token', consoleToken)
          refreshToken && localStorage.setItem('refresh_token', refreshToken)
          router.replace(pathname)
        }
        const response: RegAndLoginResponse = await regAndLogin({ body: { userId: currentUserId } })
        localStorage.setItem('console_token', response.data.access_token)
        localStorage.setItem('refresh_token', response.data.refresh_token)
        setInit(true)
        // if (!isFinished) {
        //   router.replace('/install')
        //   return
        // }
        // if (!((consoleToken && refreshToken) || (consoleTokenFromLocalStorage && refreshTokenFromLocalStorage))) {
        //   router.replace('/signin')
        //   return
        // }
        // if (searchParams.has('access_token') || searchParams.has('refresh_token')) {
        //   consoleToken && localStorage.setItem('console_token', consoleToken)
        //   refreshToken && localStorage.setItem('refresh_token', refreshToken)
        //   router.replace(pathname)
        // }
        // setInit(true)
      }
      catch (error) {
        router.replace('/signin')
app/signin/_header.tsx
@@ -5,13 +5,13 @@
import { languages } from '@/i18n/language'
import { type Locale } from '@/i18n'
import I18n from '@/context/i18n'
import LogoSite from '@/app/components/base/logo/logo-site'
// import LogoSite from '@/app/components/base/logo/logo-site'
const Header = () => {
  const { locale, setLocaleOnClient } = useContext(I18n)
  return <div className='flex items-center justify-between p-6 w-full'>
    <LogoSite />
    {/* <LogoSite /> */}
    <Select
      value={locale}
      items={languages.filter(item => item.supported)}
app/signin/layout.tsx
@@ -30,9 +30,9 @@
            {children}
          </div>
        </div>
        <div className='px-8 py-6 system-xs-regular text-text-tertiary'>
        {/* <div className='px-8 py-6 system-xs-regular text-text-tertiary'>
          © {new Date().getFullYear()} LangGenius, Inc. All rights reserved.
        </div>
        </div> */}
      </div>
    </div>
  </>
i18n/zh-Hans/app-debug.ts
@@ -103,8 +103,8 @@
      edit: '编辑标注',
    },
    dataSet: {
      title: '上下文',
      noData: '您可以导入知识库作为上下文',
      title: '知识库',
      noData: '您可以添加已有或创建新的知识库',
      words: '词',
      textBlocks: '文本块',
      selectTitle: '选择引用知识库',
@@ -518,7 +518,7 @@
    nextIteration: '下一次迭代',
    promptPlaceholder: '在这里写下您的提示词',
    tools: {
      name: '工具',
      name: '插件或工作流',
      description: '使用工具可以扩展代理的能力,比如搜索互联网或科学计算',
      enabled: '启用',
    },
i18n/zh-Hans/app.ts
@@ -3,7 +3,7 @@
  types: {
    all: '全部',
    chatbot: '聊天助手',
    agent: 'Agent',
    agent: '智能体',
    workflow: '工作流',
    completion: '文本生成',
    advanced: 'Chatflow',
i18n/zh-Hans/login.ts
@@ -1,6 +1,6 @@
const translation = {
  pageTitle: '嗨,近来可好',
  welcome: '👋 欢迎来到 Dify, 登录以继续',
  welcome: '👋 欢迎来到 Qxueyou, 登录以继续',
  email: '邮箱',
  emailPlaceholder: '输入邮箱地址',
  password: '密码',
i18n/zh-Hant/app-debug.ts
@@ -394,7 +394,7 @@
    nextIteration: '下一次迭代',
    promptPlaceholder: '在這裡寫下您的提示詞',
    tools: {
      name: '工具',
      name: '插件或工作流',
      description: '使用工具可以擴充套件代理的能力,比如搜尋網際網路或科學計算',
      enabled: '啟用',
    },
models/common.ts
@@ -4,6 +4,16 @@
  result: 'success' | 'fail'
}
export type RegAndLoginResponse = {
  result: 'success' | 'fail'
  data: RegAndLoginData
}
type RegAndLoginData = {
  access_token: string
  refresh_token: string
}
export type OauthResponse = {
  redirect_url: string
}
public/avatar/agent.png
public/avatar/workflow.png
service/common.ts
@@ -73,6 +73,10 @@
  return get<SetupStatusResponse>('/setup')
}
export const regAndLogin: Fetcher<CommonResponse, { body: Record<string, any> }> = ({ body }) => {
  return post<CommonResponse>('/regAndLogin', { body })
}
export const fetchUserProfile: Fetcher<UserProfileOriginResponse, { url: string; params: Record<string, any> }> = ({ url, params }) => {
  return get<UserProfileOriginResponse>(url, params, { needAllResponseContent: true })
}