Quellcode durchsuchen

feat: frontend multi models support (#804)

Co-authored-by: StyleZhang <jasonapring2015@outlook.com>
Co-authored-by: Joel <iamjoel007@gmail.com>
takatost vor 1 Jahr
Ursprung
Commit
d10ef17f17
100 geänderte Dateien mit 2866 neuen und 230 gelöschten Zeilen
  1. 4 2
      web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/page.tsx
  2. 1 1
      web/app/(commonLayout)/list.module.css
  3. 250 135
      web/app/components/app/configuration/config-model/index.tsx
  4. 21 15
      web/app/components/app/configuration/config-model/model-icon.tsx
  5. 29 0
      web/app/components/app/configuration/config-model/model-name.tsx
  6. 4 4
      web/app/components/app/configuration/config-model/param-item.tsx
  7. 24 0
      web/app/components/app/configuration/config-model/provider-name.tsx
  8. 1 1
      web/app/components/app/configuration/debug/index.tsx
  9. 1 0
      web/app/components/app/configuration/index.tsx
  10. 127 0
      web/app/components/app/overview/apikey-info-panel/index.tsx
  11. 29 0
      web/app/components/app/overview/apikey-info-panel/progress/index.tsx
  12. 0 8
      web/app/components/header/account-setting/provider-page/openai-hosted-provider/index.module.css
  13. 1 1
      web/app/components/app/overview/appCard.tsx
  14. 1 1
      web/app/components/app/overview/appChart.tsx
  15. 3 0
      web/app/components/base/confirm/common.module.css
  16. 69 0
      web/app/components/base/confirm/common.tsx
  17. BIN
      web/app/components/base/icons/assets/image/llm/minimax-text.png
  18. BIN
      web/app/components/base/icons/assets/image/llm/minimax.png
  19. BIN
      web/app/components/base/icons/assets/image/llm/tongyi-text-cn.png
  20. BIN
      web/app/components/base/icons/assets/image/llm/tongyi-text.png
  21. BIN
      web/app/components/base/icons/assets/image/llm/tongyi.png
  22. BIN
      web/app/components/base/icons/assets/image/llm/wxyy-text-cn.png
  23. BIN
      web/app/components/base/icons/assets/image/llm/wxyy-text.png
  24. BIN
      web/app/components/base/icons/assets/image/llm/wxyy.png
  25. 78 0
      web/app/components/base/icons/assets/public/llm/anthropic-text.svg
  26. 1 9
      web/app/components/base/icons/assets/public/llm/anthropic.svg
  27. 25 0
      web/app/components/base/icons/assets/public/llm/azure-openai-service-text.svg
  28. 7 0
      web/app/components/base/icons/assets/public/llm/azure-openai-service.svg
  29. 30 0
      web/app/components/base/icons/assets/public/llm/azureai-text.svg
  30. 23 0
      web/app/components/base/icons/assets/public/llm/azureai.svg
  31. 16 0
      web/app/components/base/icons/assets/public/llm/chatglm-text.svg
  32. 9 0
      web/app/components/base/icons/assets/public/llm/chatglm.svg
  33. 45 0
      web/app/components/base/icons/assets/public/llm/huggingface-text-hub.svg
  34. 42 0
      web/app/components/base/icons/assets/public/llm/huggingface-text.svg
  35. 19 0
      web/app/components/base/icons/assets/public/llm/huggingface.svg
  36. 11 0
      web/app/components/base/icons/assets/public/llm/iflytek-spark-text-cn.svg
  37. 24 0
      web/app/components/base/icons/assets/public/llm/iflytek-spark-text.svg
  38. 5 0
      web/app/components/base/icons/assets/public/llm/iflytek-spark.svg
  39. 8 0
      web/app/components/base/icons/assets/public/llm/microsoft.svg
  40. 4 0
      web/app/components/base/icons/assets/public/llm/openai-black.svg
  41. 4 0
      web/app/components/base/icons/assets/public/llm/openai-blue.svg
  42. 4 0
      web/app/components/base/icons/assets/public/llm/openai-green.svg
  43. 8 0
      web/app/components/base/icons/assets/public/llm/openai-text.svg
  44. 3 0
      web/app/components/base/icons/assets/public/llm/openai-transparent.svg
  45. 4 0
      web/app/components/base/icons/assets/public/llm/openai-violet.svg
  46. 13 0
      web/app/components/base/icons/assets/public/llm/replicate-text.svg
  47. 4 0
      web/app/components/base/icons/assets/public/llm/replicate.svg
  48. 5 0
      web/app/components/base/icons/assets/vender/line/alertsAndFeedback/alert-circle.svg
  49. 5 0
      web/app/components/base/icons/assets/vender/line/arrows/chevron-down-double.svg
  50. 10 0
      web/app/components/base/icons/assets/vender/line/general/at-sign.svg
  51. 9 0
      web/app/components/base/icons/assets/vender/line/general/dots-horizontal.svg
  52. 3 0
      web/app/components/base/icons/assets/vender/line/general/help-circle.svg
  53. 10 0
      web/app/components/base/icons/assets/vender/line/general/info-circle.svg
  54. 5 0
      web/app/components/base/icons/assets/vender/line/general/plus.svg
  55. 5 0
      web/app/components/base/icons/assets/vender/line/general/search-lg.svg
  56. 10 0
      web/app/components/base/icons/assets/vender/line/mapsAndTravel/globe-01.svg
  57. 13 0
      web/app/components/base/icons/assets/vender/line/shapes/cube-outline.svg
  58. 5 0
      web/app/components/base/icons/assets/vender/line/users/user-01.svg
  59. 5 0
      web/app/components/base/icons/assets/vender/line/users/users-01.svg
  60. 5 0
      web/app/components/base/icons/assets/vender/solid/FinanceAndECommerce/scales-02.svg
  61. 4 0
      web/app/components/base/icons/assets/vender/solid/editor/brush-01.svg
  62. 5 0
      web/app/components/base/icons/assets/vender/solid/general/target-04.svg
  63. 8 0
      web/app/components/base/icons/assets/vender/solid/mediaAndDevices/sliders-02.svg
  64. 5 0
      web/app/components/base/icons/assets/vender/solid/security/lock-01.svg
  65. 8 0
      web/app/components/base/icons/assets/vender/solid/users/user-01.svg
  66. 10 0
      web/app/components/base/icons/assets/vender/solid/users/users-01.svg
  67. 52 0
      web/app/components/base/icons/script.js
  68. 5 0
      web/app/components/base/icons/src/image/llm/Minimax.module.css
  69. 13 0
      web/app/components/base/icons/src/image/llm/Minimax.tsx
  70. 5 0
      web/app/components/base/icons/src/image/llm/MinimaxText.module.css
  71. 13 0
      web/app/components/base/icons/src/image/llm/MinimaxText.tsx
  72. 5 0
      web/app/components/base/icons/src/image/llm/Tongyi.module.css
  73. 13 0
      web/app/components/base/icons/src/image/llm/Tongyi.tsx
  74. 5 0
      web/app/components/base/icons/src/image/llm/TongyiText.module.css
  75. 13 0
      web/app/components/base/icons/src/image/llm/TongyiText.tsx
  76. 5 0
      web/app/components/base/icons/src/image/llm/TongyiTextCn.module.css
  77. 13 0
      web/app/components/base/icons/src/image/llm/TongyiTextCn.tsx
  78. 5 0
      web/app/components/base/icons/src/image/llm/Wxyy.module.css
  79. 13 0
      web/app/components/base/icons/src/image/llm/Wxyy.tsx
  80. 5 0
      web/app/components/base/icons/src/image/llm/WxyyText.module.css
  81. 13 0
      web/app/components/base/icons/src/image/llm/WxyyText.tsx
  82. 5 0
      web/app/components/base/icons/src/image/llm/WxyyTextCn.module.css
  83. 13 0
      web/app/components/base/icons/src/image/llm/WxyyTextCn.tsx
  84. 8 0
      web/app/components/base/icons/src/image/llm/index.ts
  85. 3 53
      web/app/components/base/icons/src/public/llm/Anthropic.json
  86. 539 0
      web/app/components/base/icons/src/public/llm/AnthropicText.json
  87. 14 0
      web/app/components/base/icons/src/public/llm/AnthropicText.tsx
  88. 74 0
      web/app/components/base/icons/src/public/llm/AzureOpenaiService.json
  89. 14 0
      web/app/components/base/icons/src/public/llm/AzureOpenaiService.tsx
  90. 236 0
      web/app/components/base/icons/src/public/llm/AzureOpenaiServiceText.json
  91. 14 0
      web/app/components/base/icons/src/public/llm/AzureOpenaiServiceText.tsx
  92. 180 0
      web/app/components/base/icons/src/public/llm/Azureai.json
  93. 14 0
      web/app/components/base/icons/src/public/llm/Azureai.tsx
  94. 243 0
      web/app/components/base/icons/src/public/llm/AzureaiText.json
  95. 14 0
      web/app/components/base/icons/src/public/llm/AzureaiText.tsx
  96. 72 0
      web/app/components/base/icons/src/public/llm/Chatglm.json
  97. 14 0
      web/app/components/base/icons/src/public/llm/Chatglm.tsx
  98. 135 0
      web/app/components/base/icons/src/public/llm/ChatglmText.json
  99. 14 0
      web/app/components/base/icons/src/public/llm/ChatglmText.tsx
  100. 0 0
      web/app/components/base/icons/src/public/llm/Huggingface.json

+ 4 - 2
web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/page.tsx

@@ -1,9 +1,10 @@
 import React from 'react'
-import WelcomeBanner, { EditKeyPopover } from './welcome-banner'
+import { EditKeyPopover } from './welcome-banner'
 import ChartView from './chartView'
 import CardView from './cardView'
 import { getLocaleOnServer } from '@/i18n/server'
 import { useTranslation } from '@/i18n/i18next-serverside-config'
+import ApikeyInfoPanel from '@/app/components/app/overview/apikey-info-panel'
 
 export type IDevelopProps = {
   params: { appId: string }
@@ -16,7 +17,8 @@ const Overview = async ({
   const { t } = await useTranslation(locale, 'app-overview')
   return (
     <div className="h-full px-16 py-6 overflow-scroll">
-      <WelcomeBanner />
+      {/* <WelcomeBanner /> */}
+      <ApikeyInfoPanel />
       <div className='flex flex-row items-center justify-between mb-4 text-xl text-gray-900'>
         {t('overview.title')}
         <EditKeyPopover />

+ 1 - 1
web/app/(commonLayout)/list.module.css

@@ -1,5 +1,5 @@
 .listItem {
-  @apply col-span-1 bg-white border-2 border-solid border-transparent rounded-lg shadow-sm min-h-[160px] flex flex-col transition-all duration-200 ease-in-out cursor-pointer hover:shadow-lg;
+  @apply col-span-1 bg-white border-2 border-solid border-transparent rounded-lg shadow-xs min-h-[160px] flex flex-col transition-all duration-200 ease-in-out cursor-pointer hover:shadow-lg;
 }
 
 .listItem.newItemCard {

+ 250 - 135
web/app/components/app/configuration/config-model/index.tsx

@@ -3,22 +3,34 @@ import type { FC } from 'react'
 import React, { useEffect, useState } from 'react'
 import cn from 'classnames'
 import { useTranslation } from 'react-i18next'
-import { useBoolean, useClickAway } from 'ahooks'
-import { ChevronDownIcon, Cog8ToothIcon, InformationCircleIcon } from '@heroicons/react/24/outline'
+import { useBoolean, useClickAway, useGetState } from 'ahooks'
+import { Cog8ToothIcon, InformationCircleIcon } from '@heroicons/react/24/outline'
+import produce from 'immer'
 import ParamItem from './param-item'
 import ModelIcon from './model-icon'
+import ModelName from './model-name'
 import Radio from '@/app/components/base/radio'
 import Panel from '@/app/components/base/panel'
 import type { CompletionParams } from '@/models/debug'
-import { AppType, ProviderType } from '@/types/app'
-import { MODEL_LIST, TONE_LIST } from '@/config'
+import { TONE_LIST } from '@/config'
 import Toast from '@/app/components/base/toast'
 import { AlertTriangle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback'
 import { formatNumber } from '@/utils/format'
-export type IConifgModelProps = {
+import { Brush01 } from '@/app/components/base/icons/src/vender/solid/editor'
+import { Scales02 } from '@/app/components/base/icons/src/vender/solid/FinanceAndECommerce'
+import { Target04 } from '@/app/components/base/icons/src/vender/solid/general'
+import { Sliders02 } from '@/app/components/base/icons/src/vender/solid/mediaAndDevices'
+import { fetchModelParams } from '@/service/debug'
+import Loading from '@/app/components/base/loading'
+import ModelSelector from '@/app/components/header/account-setting/model-page/model-selector'
+import { ModelType, ProviderEnum } from '@/app/components/header/account-setting/model-page/declarations'
+import { useProviderContext } from '@/context/provider-context'
+
+export type IConfigModelProps = {
   mode: string
   modelId: string
-  setModelId: (id: string, provider: ProviderType) => void
+  provider: ProviderEnum
+  setModelId: (id: string, provider: ProviderEnum) => void
   completionParams: CompletionParams
   onCompletionParamsChange: (newParams: CompletionParams) => void
   disabled: boolean
@@ -26,21 +38,10 @@ export type IConifgModelProps = {
   onShowUseGPT4Confirm: () => void
 }
 
-const options = MODEL_LIST
-
-const getMaxToken = (modelId: string) => {
-  if (['claude-instant-1', 'claude-2'].includes(modelId))
-    return 30 * 1000
-
-  if (['gpt-4', 'gpt-3.5-turbo-16k'].includes(modelId))
-    return 8000
-
-  return 4000
-}
-
-const ConifgModel: FC<IConifgModelProps> = ({
-  mode,
+const ConfigModel: FC<IConfigModelProps> = ({
+  // mode,
   modelId,
+  provider,
   setModelId,
   completionParams,
   onCompletionParamsChange,
@@ -49,89 +50,140 @@ const ConifgModel: FC<IConifgModelProps> = ({
   onShowUseGPT4Confirm,
 }) => {
   const { t } = useTranslation()
-  const isChatApp = mode === AppType.chat
-  const availableModels = options.filter(item => item.type === mode)
+  const { textGenerationModelList } = useProviderContext()
   const [isShowConfig, { setFalse: hideConfig, toggle: toogleShowConfig }] = useBoolean(false)
   const [maxTokenSettingTipVisible, setMaxTokenSettingTipVisible] = useState(false)
   const configContentRef = React.useRef(null)
-  const currModel = options.find(item => item.id === modelId)
+  const currModel = textGenerationModelList.find(item => item.model_name === modelId)
+  // Cache loaded model param
+  const [allParams, setAllParams, getAllParams] = useGetState<Record<string, Record<string, any>>>({})
+  const currParams = allParams[provider]?.[modelId]
+  const hasEnableParams = currParams && Object.keys(currParams).some(key => currParams[key].enabled)
+  const allSupportParams = ['temperature', 'top_p', 'presence_penalty', 'frequency_penalty', 'max_tokens']
+  const currSupportParams = currParams ? allSupportParams.filter(key => currParams[key].enabled) : allSupportParams
+
+  useEffect(() => {
+    (async () => {
+      if (!allParams[provider]?.[modelId]) {
+        const res = await fetchModelParams(provider, modelId)
+        const newAllParams = produce(allParams, (draft) => {
+          if (!draft[provider])
+            draft[provider] = {}
+
+          draft[provider][modelId] = res
+        })
+        setAllParams(newAllParams)
+      }
+    })()
+  }, [provider, modelId])
+
   useClickAway(() => {
     hideConfig()
   }, configContentRef)
 
-  const params = [
-    {
-      id: 1,
-      name: t('common.model.params.temperature'),
-      key: 'temperature',
-      tip: t('common.model.params.temperatureTip'),
-      max: 2,
-    },
-    {
-      id: 2,
-      name: t('common.model.params.topP'),
-      key: 'top_p',
-      tip: t('common.model.params.topPTip'),
-      max: 1,
-    },
-    {
-      id: 3,
-      name: t('common.model.params.presencePenalty'),
-      key: 'presence_penalty',
-      tip: t('common.model.params.presencePenaltyTip'),
-      min: -2,
-      max: 2,
-    },
-    {
-      id: 4,
-      name: t('common.model.params.frequencyPenalty'),
-      key: 'frequency_penalty',
-      tip: t('common.model.params.frequencyPenaltyTip'),
-      min: -2,
-      max: 2,
-    },
-    {
-      id: 5,
-      name: t('common.model.params.maxToken'),
-      key: 'max_tokens',
-      tip: t('common.model.params.maxTokenTip'),
-      step: 100,
-      max: getMaxToken(modelId),
-    },
-  ]
-
-  const selectModelDisabled = false // chat  gpt-3.5-turbo, gpt-4; text generation text-davinci-003, gpt-3.5-turbo
-
   const selectedModel = { name: modelId } // options.find(option => option.id === modelId)
-  const [isShowOption, { setFalse: hideOption, toggle: toogleOption }] = useBoolean(false)
-  const triggerRef = React.useRef(null)
-  useClickAway(() => {
-    hideOption()
-  }, triggerRef)
 
-  const handleSelectModel = (id: string, provider = ProviderType.openai) => {
-    return () => {
+  const ensureModelParamLoaded = (provider: ProviderEnum, modelId: string) => {
+    return new Promise<void>((resolve) => {
+      if (getAllParams()[provider]?.[modelId]) {
+        resolve()
+        return
+      }
+      const runId = setInterval(() => {
+        if (getAllParams()[provider]?.[modelId]) {
+          resolve()
+          clearInterval(runId)
+        }
+      }, 500)
+    })
+  }
+
+  const transformValue = (value: number, fromRange: [number, number], toRange: [number, number]): number => {
+    const [fromStart = 0, fromEnd] = fromRange
+    const [toStart = 0, toEnd] = toRange
+
+    // The following three if is to avoid precision loss
+    if (fromStart === toStart && fromEnd === toEnd)
+      return value
+
+    if (value <= fromStart)
+      return toStart
+
+    if (value >= fromEnd)
+      return toEnd
+
+    const fromLength = fromEnd - fromStart
+    const toLength = toEnd - toStart
+
+    let adjustedValue = (value - fromStart) * (toLength / fromLength) + toStart
+    adjustedValue = parseFloat(adjustedValue.toFixed(2))
+    return adjustedValue
+  }
+
+  const handleSelectModel = (id: string, nextProvider = ProviderEnum.openai) => {
+    return async () => {
       if (id === 'gpt-4' && !canUseGPT4) {
         hideConfig()
-        hideOption()
         onShowUseGPT4Confirm()
         return
       }
-      const nextSelectModelMaxToken = getMaxToken(id)
-      if (completionParams.max_tokens > nextSelectModelMaxToken) {
-        Toast.notify({
-          type: 'warning',
-          message: t('common.model.params.setToCurrentModelMaxTokenTip', { maxToken: formatNumber(nextSelectModelMaxToken) }),
-        })
-        onCompletionParamsChange({
-          ...completionParams,
-          max_tokens: nextSelectModelMaxToken,
+      const prevParamsRule = getAllParams()[provider]?.[modelId]
+
+      setModelId(id, nextProvider)
+
+      await ensureModelParamLoaded(nextProvider, id)
+
+      const nextParamsRule = getAllParams()[nextProvider]?.[id]
+      // debugger
+      const nextSelectModelMaxToken = nextParamsRule.max_tokens.max
+      const newConCompletionParams = produce(completionParams, (draft: any) => {
+        if (nextParamsRule.max_tokens.enabled) {
+          if (completionParams.max_tokens > nextSelectModelMaxToken) {
+            Toast.notify({
+              type: 'warning',
+              message: t('common.model.params.setToCurrentModelMaxTokenTip', { maxToken: formatNumber(nextSelectModelMaxToken) }),
+            })
+            draft.max_tokens = parseFloat((nextSelectModelMaxToken * 0.8).toFixed(2))
+          }
+          // prev don't have max token
+          if (!completionParams.max_tokens)
+            draft.max_tokens = nextParamsRule.max_tokens.default
+        }
+        else {
+          delete draft.max_tokens
+        }
+
+        allSupportParams.forEach((key) => {
+          if (key === 'max_tokens')
+            return
+
+          if (!nextParamsRule[key].enabled) {
+            delete draft[key]
+            return
+          }
+
+          if (draft[key] === undefined) {
+            draft[key] = nextParamsRule[key].default || 0
+            return
+          }
+
+          if (!prevParamsRule[key].enabled) {
+            draft[key] = nextParamsRule[key].default || 0
+            return
+          }
+
+          draft[key] = transformValue(
+            draft[key],
+            [prevParamsRule[key].min, prevParamsRule[key].max],
+            [nextParamsRule[key].min, nextParamsRule[key].max],
+          )
         })
-      }
-      setModelId(id, provider)
+      })
+      onCompletionParamsChange(newConCompletionParams)
     }
   }
 
+  // only openai support this
   function matchToneId(completionParams: CompletionParams): number {
     const remvoedCustomeTone = TONE_LIST.slice(0, -1)
     const CUSTOM_TONE_ID = 4
@@ -146,6 +198,11 @@ const ConifgModel: FC<IConifgModelProps> = ({
 
   // tone is a preset of completionParams.
   const [toneId, setToneId] = React.useState(matchToneId(completionParams)) // default is Balanced
+  const toneTabBgClassName = ({
+    1: 'bg-[#F5F8FF]',
+    2: 'bg-[#F4F3FF]',
+    3: 'bg-[#F6FEFC]',
+  })[toneId] || ''
   // set completionParams by toneId
   const handleToneChange = (id: number) => {
     if (id === 4)
@@ -164,40 +221,59 @@ const ConifgModel: FC<IConifgModelProps> = ({
     setToneId(matchToneId(completionParams))
   }, [completionParams])
 
-  const handleParamChange = (id: number, value: number) => {
-    const key = params.find(item => item.id === id)?.key
+  const handleParamChange = (key: string, value: number) => {
+    const currParamsRule = getAllParams()[provider]?.[modelId]
+    let notOutRangeValue = parseFloat(value.toFixed(2))
+    notOutRangeValue = Math.max(currParamsRule[key].min, notOutRangeValue)
+    notOutRangeValue = Math.min(currParamsRule[key].max, notOutRangeValue)
 
-    if (key) {
-      onCompletionParamsChange({
-        ...completionParams,
-        [key]: value,
-      })
-    }
+    onCompletionParamsChange({
+      ...completionParams,
+      [key]: notOutRangeValue,
+    })
   }
   const ableStyle = 'bg-indigo-25 border-[#2A87F5] cursor-pointer'
   const diabledStyle = 'bg-[#FFFCF5] border-[#F79009]'
 
+  const getToneIcon = (toneId: number) => {
+    const className = 'w-[14px] h-[14px]'
+    const res = ({
+      1: <Brush01 className={className}/>,
+      2: <Scales02 className={className} />,
+      3: <Target04 className={className} />,
+      4: <Sliders02 className={className} />,
+    })[toneId]
+    return res
+  }
   useEffect(() => {
-    const max = params[4].max
-    if (currModel?.provider !== ProviderType.anthropic && completionParams.max_tokens > max * 2 / 3)
+    if (!currParams)
+      return
+
+    const max = currParams.max_tokens.max
+    const isSupportMaxToken = currParams.max_tokens.enabled
+    if (isSupportMaxToken && currModel?.model_provider.provider_name !== ProviderEnum.anthropic && completionParams.max_tokens > max * 2 / 3)
       setMaxTokenSettingTipVisible(true)
     else
       setMaxTokenSettingTipVisible(false)
-  }, [params, completionParams.max_tokens, setMaxTokenSettingTipVisible])
-
+  }, [currParams, completionParams.max_tokens, setMaxTokenSettingTipVisible])
   return (
     <div className='relative' ref={configContentRef}>
       <div
         className={cn('flex items-center border h-8 px-2.5 space-x-2 rounded-lg', disabled ? diabledStyle : ableStyle)}
         onClick={() => !disabled && toogleShowConfig()}
       >
-        <ModelIcon modelId={currModel?.id as string} />
-        <div className='text-[13px] text-gray-900 font-medium'>{selectedModel.name}</div>
+        <ModelIcon
+          modelId={modelId}
+          providerName={provider}
+        />
+        <div className='text-[13px] text-gray-900 font-medium'>
+          <ModelName modelId={selectedModel.name} />
+        </div>
         {disabled ? <InformationCircleIcon className='w-3.5 h-3.5 text-[#F79009]' /> : <Cog8ToothIcon className='w-3.5 h-3.5 text-gray-500' />}
       </div>
       {isShowConfig && (
         <Panel
-          className='absolute z-20 top-8 right-0 !w-[496px] bg-white'
+          className='absolute z-20 top-8 right-0 !w-[496px] bg-white !overflow-visible shadow-md'
           keepUnFold
           headerIcon={
             <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
@@ -215,49 +291,88 @@ const ConifgModel: FC<IConifgModelProps> = ({
           <div className='py-3 pl-10 pr-6 text-sm'>
             <div className="flex items-center justify-between my-5 h-9">
               <div>{t('appDebug.modelConfig.model')}</div>
-              {/* model selector */}
-              <div className="relative" style={{ zIndex: 30 }}>
-                <div ref={triggerRef} onClick={() => !selectModelDisabled && toogleOption()} className={cn(selectModelDisabled ? 'cursor-not-allowed' : 'cursor-pointer', 'flex items-center h-9 px-3 space-x-2 rounded-lg bg-gray-50 ')}>
-                  <ModelIcon modelId={currModel?.id as string} />
-                  <div className="text-sm gray-900">{selectedModel?.name}</div>
-                  {!selectModelDisabled && <ChevronDownIcon className={cn(isShowOption && 'rotate-180', 'w-[14px] h-[14px] text-gray-500')} />}
-                </div>
-                {isShowOption && (
-                  <div className={cn(isChatApp ? 'min-w-[159px]' : 'w-[179px]', 'absolute right-0 bg-gray-50 rounded-lg shadow')}>
-                    {availableModels.map(item => (
-                      <div key={item.id} onClick={handleSelectModel(item.id, item.provider)} className="flex items-center h-9 px-3 rounded-lg cursor-pointer hover:bg-gray-100">
-                        <ModelIcon className='shrink-0 mr-2' modelId={item?.id} />
-                        <div className="text-sm gray-900 whitespace-nowrap">{item.name}</div>
+              <ModelSelector
+                popClassName='right-0'
+                triggerIconSmall
+                value={{
+                  modelName: modelId,
+                  providerName: provider,
+                }}
+                modelType={ModelType.textGeneration}
+                onChange={(model) => {
+                  handleSelectModel(model.model_name, model.model_provider.provider_name as ProviderEnum)()
+                }}
+              />
+            </div>
+            {hasEnableParams && (
+              <div className="border-b border-gray-100"></div>
+            )}
+
+            {/* Tone type */}
+            {[ProviderEnum.openai, ProviderEnum.azure_openai].includes(provider) && (
+              <div className="mt-5 mb-4">
+                <div className="mb-3 text-sm text-gray-900">{t('appDebug.modelConfig.setTone')}</div>
+                <Radio.Group className={cn('!rounded-lg', toneTabBgClassName)} value={toneId} onChange={handleToneChange}>
+                  <>
+                    {TONE_LIST.slice(0, 3).map(tone => (
+                      <div className='grow flex items-center' key={tone.id}>
+                        <Radio
+                          value={tone.id}
+                          className={cn(tone.id === toneId && 'rounded-md border border-gray-200 shadow-md', '!mr-0 grow !px-2 !justify-center text-[13px] font-medium')}
+                          labelClassName={cn(tone.id === toneId
+                            ? ({
+                              1: 'text-[#6938EF]',
+                              2: 'text-[#444CE7]',
+                              3: 'text-[#107569]',
+                            })[toneId]
+                            : 'text-[#667085]', 'flex items-center space-x-2')}
+                        >
+                          <>
+                            {getToneIcon(tone.id)}
+                            <div>{t(`common.model.tone.${tone.name}`) as string}</div>
+                            <div className=""></div>
+                          </>
+                        </Radio>
+                        {tone.id !== toneId && tone.id + 1 !== toneId && (<div className='h-5 border-r border-gray-200'></div>)}
                       </div>
                     ))}
-                  </div>
-                )}
+                  </>
+                  <Radio
+                    value={TONE_LIST[3].id}
+                    className={cn(toneId === 4 && 'rounded-md border border-gray-200 shadow-md', '!mr-0 grow !px-2 !justify-center text-[13px] font-medium')}
+                    labelClassName={cn('flex items-center space-x-2 ', toneId === 4 ? 'text-[#155EEF]' : 'text-[#667085]')}
+                  >
+                    <>
+                      {getToneIcon(TONE_LIST[3].id)}
+                      <div>{t(`common.model.tone.${TONE_LIST[3].name}`) as string}</div>
+                    </>
+                  </Radio>
+                </Radio.Group>
               </div>
-            </div>
-            <div className="border-b border-gray-100"></div>
-
-            {/* Response type */}
-            <div className="mt-5 mb-4">
-              <div className="mb-4 text-sm text-gray-900">{t('appDebug.modelConfig.setTone')}</div>
-              <Radio.Group value={toneId} onChange={handleToneChange}>
-                <>
-                  {TONE_LIST.slice(0, 3).map(tone => (
-                    <Radio key={tone.id} value={tone.id} className="grow !px-0 !justify-center">{t(`common.model.tone.${tone.name}`) as string}</Radio>
-                  ))}
-                </>
-                <div className="ml-[2px] mr-[3px] h-5 border-r border-gray-200"></div>
-                <Radio value={TONE_LIST[3].id}>{t(`common.model.tone.${TONE_LIST[3].name}`) as string}</Radio>
-              </Radio.Group>
-            </div>
+            )}
 
             {/* Params */}
-            <div className="mt-4 space-y-4">
-              {params.map(({ key, ...param }) => (<ParamItem key={key} {...param} value={(completionParams as any)[key] as any} onChange={handleParamChange} />))}
+            <div className={cn(hasEnableParams && 'mt-4', 'space-y-4', !allParams[provider]?.[modelId] && 'flex items-center min-h-[200px]')}>
+              {allParams[provider]?.[modelId]
+                ? (
+                  currSupportParams.map(key => (<ParamItem
+                    key={key}
+                    id={key}
+                    name={t(`common.model.params.${key}`)}
+                    tip={t(`common.model.params.${key}Tip`)}
+                    {...currParams[key] as any}
+                    value={(completionParams as any)[key] as any}
+                    onChange={handleParamChange}
+                  />))
+                )
+                : (
+                  <Loading type='area'/>
+                )}
             </div>
           </div>
           {
             maxTokenSettingTipVisible && (
-              <div className='flex py-2 pr-4 pl-5 bg-[#FFFAEB] border-t border-[#FEF0C7]'>
+              <div className='flex py-2 pr-4 pl-5 rounded-bl-xl rounded-br-xl bg-[#FFFAEB] border-t border-[#FEF0C7]'>
                 <AlertTriangle className='shrink-0 mr-2 mt-[3px] w-3 h-3 text-[#F79009]' />
                 <div className='mr-2 text-xs font-medium text-gray-700'>{t('common.model.params.maxTokenSettingTip')}</div>
               </div>
@@ -270,4 +385,4 @@ const ConifgModel: FC<IConifgModelProps> = ({
   )
 }
 
-export default React.memo(ConifgModel)
+export default React.memo(ConfigModel)

+ 21 - 15
web/app/components/app/configuration/config-model/model-icon.tsx

@@ -1,25 +1,31 @@
 'use client'
 import type { FC } from 'react'
 import React from 'react'
-import { ProviderType } from '@/types/app'
-import { MODEL_LIST } from '@/config'
-import { Anthropic, Gpt3, Gpt4 } from '@/app/components/base/icons/src/public/llm'
+import cn from 'classnames'
+import {
+  OpenaiGreen,
+  OpenaiViolet,
+} from '@/app/components/base/icons/src/public/llm'
+import { ProviderEnum } from '@/app/components/header/account-setting/model-page/declarations'
+import ProviderConfig from '@/app/components/header/account-setting/model-page/configs'
 
-export type IModelIconProps = { modelId: string; className?: string }
+export type IModelIconProps = {
+  modelId: string
+  providerName: ProviderEnum
+  className?: string
+}
 
-const ModelIcon: FC<IModelIconProps> = ({ modelId, className }) => {
-  const resClassName = `w-4 h-4 ${className}`
-  const model = MODEL_LIST.find(item => item.id === modelId)
-  if (model?.id === 'gpt-4')
-    return <Gpt4 className={resClassName} />
+const ModelIcon: FC<IModelIconProps> = ({ modelId, providerName, className }) => {
+  let Icon = <OpenaiGreen className='w-full h-full' />
+  if (providerName === ProviderEnum.openai)
+    Icon = modelId.includes('gpt-4') ? <OpenaiViolet className='w-full h-full' /> : <OpenaiGreen className='w-full h-full' />
+  else
+    Icon = ProviderConfig[providerName]?.selector.icon
 
-  if (model?.provider === ProviderType.anthropic) {
-    return (
-      <Anthropic className={resClassName} />
-    )
-  }
   return (
-    <Gpt3 className={resClassName} />
+    <div className={cn(className, 'w-4 h-4')}>
+      {Icon}
+    </div>
   )
 }
 

+ 29 - 0
web/app/components/app/configuration/config-model/model-name.tsx

@@ -0,0 +1,29 @@
+'use client'
+import type { FC } from 'react'
+import React from 'react'
+import { useTranslation } from 'react-i18next'
+
+export type IModelNameProps = {
+  modelId: string
+}
+
+export const supportI18nModelName = [
+  'gpt-3.5-turbo', 'gpt-3.5-turbo-16k',
+  'gpt-4', 'gpt-4-32k',
+  'text-davinci-003', 'text-embedding-ada-002', 'whisper-1',
+  'claude-instant-1', 'claude-2',
+]
+
+const ModelName: FC<IModelNameProps> = ({
+  modelId,
+}) => {
+  const { t } = useTranslation()
+  const name = supportI18nModelName.includes(modelId) ? t(`common.modelName.${modelId}`) : modelId
+
+  return (
+    <span title={name}>
+      {name}
+    </span>
+  )
+}
+export default React.memo(ModelName)

+ 4 - 4
web/app/components/app/configuration/config-model/param-item.tsx

@@ -5,21 +5,21 @@ import Tooltip from '@/app/components/base/tooltip'
 import Slider from '@/app/components/base/slider'
 
 export type IParamIteProps = {
-  id: number
+  id: string
   name: string
   tip: string
   value: number
   step?: number
   min?: number
   max: number
-  onChange: (id: number, value: number) => void
+  onChange: (key: string, value: number) => void
 }
 
 const ParamIte: FC<IParamIteProps> = ({ id, name, tip, step = 0.1, min = 0, max, value, onChange }) => {
   return (
     <div className="flex items-center justify-between">
       <div className="flex items-center">
-        <span className="mr-[6px]">{name}</span>
+        <span className="mr-[6px] text-gray-500 text-[13px] font-medium">{name}</span>
         {/* Give tooltip different tip to avoiding hide bug */}
         <Tooltip htmlContent={<div className="w-[200px]">{tip}</div>} position='top' selector={`param-name-tooltip-${id}`}>
           <svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
@@ -33,7 +33,7 @@ const ParamIte: FC<IParamIteProps> = ({ id, name, tip, step = 0.1, min = 0, max,
         </div>
         <input type="number" min={min} max={max} step={step} className="block w-[64px] h-9 leading-9 rounded-lg border-0 pl-1 pl py-1.5 bg-gray-50 text-gray-900  placeholder:text-gray-400 focus:ring-1 focus:ring-inset focus:ring-primary-600" value={value} onChange={(e) => {
           const value = parseFloat(e.target.value)
-          if (value < 0 || value > max)
+          if (value < min || value > max)
             return
 
           onChange(id, value)

+ 24 - 0
web/app/components/app/configuration/config-model/provider-name.tsx

@@ -0,0 +1,24 @@
+'use client'
+import type { FC } from 'react'
+import React from 'react'
+import { useContext } from 'use-context-selector'
+import I18n from '@/context/i18n'
+import type { ProviderEnum } from '@/app/components/header/account-setting/model-page/declarations'
+import ProviderConfig from '@/app/components/header/account-setting/model-page/configs'
+
+export type IProviderNameProps = {
+  provideName: ProviderEnum
+}
+
+const ProviderName: FC<IProviderNameProps> = ({
+  provideName,
+}) => {
+  const { locale } = useContext(I18n)
+
+  return (
+    <span>
+      {ProviderConfig[provideName]?.selector?.name[locale]}
+    </span>
+  )
+}
+export default React.memo(ProviderName)

+ 1 - 1
web/app/components/app/configuration/debug/index.tsx

@@ -12,7 +12,7 @@ import FormattingChanged from '../base/warning-mask/formatting-changed'
 import GroupName from '../base/group-name'
 import { AppType } from '@/types/app'
 import PromptValuePanel, { replaceStringWithValues } from '@/app/components/app/configuration/prompt-value-panel'
-import type { IChatItem } from '@/app/components/app/chat'
+import type { IChatItem } from '@/app/components/app/chat/type'
 import Chat from '@/app/components/app/chat'
 import ConfigContext from '@/context/debug-configuration'
 import { ToastContext } from '@/app/components/base/toast'

+ 1 - 0
web/app/components/app/configuration/index.tsx

@@ -284,6 +284,7 @@ const Configuration: FC = () => {
               {/* Model and Parameters */}
               <ConfigModel
                 mode={mode}
+                provider={modelConfig.provider as ProviderType}
                 completionParams={completionParams}
                 modelId={modelConfig.model_id}
                 setModelId={setModelId}

+ 127 - 0
web/app/components/app/overview/apikey-info-panel/index.tsx

@@ -0,0 +1,127 @@
+'use client'
+import type { FC } from 'react'
+import React, { useState } from 'react'
+import { useTranslation } from 'react-i18next'
+import cn from 'classnames'
+import useSWR from 'swr'
+import Progress from './progress'
+import Button from '@/app/components/base/button'
+import { LinkExternal02, XClose } from '@/app/components/base/icons/src/vender/line/general'
+import AccountSetting from '@/app/components/header/account-setting'
+import { fetchTenantInfo } from '@/service/common'
+import { IS_CE_EDITION } from '@/config'
+import { useProviderContext } from '@/context/provider-context'
+
+const APIKeyInfoPanel: FC = () => {
+  const isCloud = !IS_CE_EDITION
+  const { providers }: any = useProviderContext()
+
+  const { t } = useTranslation()
+
+  const [showSetAPIKeyModal, setShowSetAPIKeyModal] = useState(false)
+
+  const [isShow, setIsShow] = useState(true)
+
+  const { data: userInfo } = useSWR({ url: '/info' }, fetchTenantInfo)
+  if (!userInfo)
+    return null
+
+  const hasBindAPI = userInfo?.providers?.find(({ token_is_set }) => token_is_set)
+  if (hasBindAPI)
+    return null
+
+  // first show in trail and not used exhausted, else find the exhausted
+  const [used, total, providerName] = (() => {
+    if (!providers || !isCloud)
+      return [0, 0, '']
+    let used = 0
+    let total = 0
+    let trailProviderName = ''
+    let hasFoundNotExhausted = false
+    Object.keys(providers).forEach((providerName) => {
+      if (hasFoundNotExhausted)
+        return
+      providers[providerName].providers.forEach(({ quota_type, quota_limit, quota_used }: any) => {
+        if (quota_type === 'trial') {
+          if (quota_limit !== quota_used)
+            hasFoundNotExhausted = true
+
+          used = quota_used
+          total = quota_limit
+          trailProviderName = providerName
+        }
+      })
+    })
+    return [used, total, trailProviderName]
+  })()
+  const usedPercent = Math.round(used / total * 100)
+  const exhausted = isCloud && usedPercent === 100
+  if (!(isShow))
+    return null
+
+  return (
+    <div className={cn(exhausted ? 'bg-[#FEF3F2] border-[#FEE4E2]' : 'bg-[#EFF4FF] border-[#D1E0FF]', 'mb-6 relative  rounded-2xl shadow-md border  p-8 ')}>
+      <div className={cn('text-[24px] text-gray-800 font-semibold', isCloud ? 'flex items-center h-8 space-x-1' : 'leading-8 mb-6')}>
+        {isCloud && <em-emoji id={exhausted ? '🤔' : '😀'} />}
+        {isCloud
+          ? (
+            <div>{t(`appOverview.apiKeyInfo.cloud.${exhausted ? 'exhausted' : 'trial'}.title`, { providerName })}</div>
+          )
+          : (
+            <div>
+              <div>{t('appOverview.apiKeyInfo.selfHost.title.row1')}</div>
+              <div>{t('appOverview.apiKeyInfo.selfHost.title.row2')}</div>
+            </div>
+          )}
+      </div>
+      {isCloud && (
+        <div className='mt-1 text-sm text-gray-600 font-normal'>{t(`appOverview.apiKeyInfo.cloud.${exhausted ? 'exhausted' : 'trial'}.description`)}</div>
+      )}
+      {/* Call times info */}
+      {isCloud && (
+        <div className='my-5'>
+          <div className='flex items-center h-5 space-x-2 text-sm text-gray-700 font-medium'>
+            <div>{t('appOverview.apiKeyInfo.callTimes')}</div>
+            <div>·</div>
+            <div className={cn('font-semibold', exhausted && 'text-[#D92D20]')}>{used}/{total}</div>
+          </div>
+          <Progress className='mt-2' value={usedPercent} />
+        </div>
+      )}
+      <Button
+        type='primary'
+        className='space-x-2'
+        onClick={() => {
+          setShowSetAPIKeyModal(true)
+        }}
+      >
+        <div className='text-sm font-medium'>{t('appOverview.apiKeyInfo.setAPIBtn')}</div>
+        <LinkExternal02 className='w-4 h-4' />
+      </Button>
+      {!isCloud && (
+        <a
+          className='mt-2 flex items-center h-[26px] text-xs  font-medium text-[#155EEF] p-1 space-x-1'
+          href='https://cloud.dify.ai/apps'
+          target='_blank'
+        >
+          <div>{t('appOverview.apiKeyInfo.tryCloud')}</div>
+          <LinkExternal02 className='w-3 h-3' />
+        </a>
+      )}
+      <div
+        onClick={() => setIsShow(false)}
+        className='absolute right-4 top-4 flex items-center justify-center w-8 h-8 cursor-pointer '>
+        <XClose className='w-4 h-4 text-gray-500' />
+      </div>
+
+      {
+        showSetAPIKeyModal && (
+          <AccountSetting activeTab="provider" onCancel={async () => {
+            setShowSetAPIKeyModal(false)
+          }} />
+        )
+      }
+    </div>
+  )
+}
+export default React.memo(APIKeyInfoPanel)

+ 29 - 0
web/app/components/app/overview/apikey-info-panel/progress/index.tsx

@@ -0,0 +1,29 @@
+'use client'
+import type { FC } from 'react'
+import React from 'react'
+import cn from 'classnames'
+import s from './style.module.css'
+
+export type IProgressProps = {
+  className?: string
+  value: number // percent
+}
+
+const Progress: FC<IProgressProps> = ({
+  className,
+  value,
+}) => {
+  const exhausted = value === 100
+  return (
+    <div className={cn(className, 'relative grow h-2 flex bg-gray-200 rounded-md overflow-hidden')}>
+      <div
+        className={cn(s.bar, exhausted && s['bar-error'], 'absolute top-0 left-0 right-0 bottom-0')}
+        style={{ width: `${value}%` }}
+      />
+      {Array(10).fill(0).map((i, k) => (
+        <div key={k} className={s['bar-item']} />
+      ))}
+    </div>
+  )
+}
+export default React.memo(Progress)

+ 0 - 8
web/app/components/header/account-setting/provider-page/openai-hosted-provider/index.module.css

@@ -1,11 +1,3 @@
-.icon {
-  width: 24px;
-  height: 24px;
-  margin-right: 12px;
-  background: url(../../../assets/gpt.svg) center center no-repeat;
-  background-size: contain;
-}
-
 .bar {
   background: linear-gradient(90deg, rgba(41, 112, 255, 0.9) 0%, rgba(21, 94, 239, 0.9) 100%);
 }

+ 1 - 1
web/app/components/app/overview/appCard.tsx

@@ -110,7 +110,7 @@ function AppCard({
 
   return (
     <div
-      className={`flex flex-col w-full shadow-sm border-[0.5px] rounded-lg border-gray-200 ${className ?? ''}`}
+      className={`flex flex-col w-full shadow-xs border-[0.5px] rounded-lg border-gray-200 ${className ?? ''}`}
     >
       <div className={`px-6 py-4 ${customBgColor ?? bgColor} rounded-lg`}>
         <div className="mb-2.5 flex flex-row items-start justify-between">

+ 1 - 1
web/app/components/app/overview/appChart.tsx

@@ -225,7 +225,7 @@ const Chart: React.FC<IChartProps> = ({
   const sumData = isAvg ? (sum(yData) / yData.length) : sum(yData)
 
   return (
-    <div className={`flex flex-col w-full px-6 py-4 border-[0.5px] rounded-lg border-gray-200 shadow-sm ${className ?? ''}`}>
+    <div className={`flex flex-col w-full px-6 py-4 border-[0.5px] rounded-lg border-gray-200 shadow-xs ${className ?? ''}`}>
       <div className='mb-3'>
         <Basic name={title} type={timePeriod} hoverTip={explanation} />
       </div>

+ 3 - 0
web/app/components/base/confirm/common.module.css

@@ -0,0 +1,3 @@
+.wrapper {
+  background: linear-gradient(180deg, rgba(217, 45, 32, 0.05) 0%, rgba(217, 45, 32, 0.00) 24.02%), #F9FAFB;
+}

+ 69 - 0
web/app/components/base/confirm/common.tsx

@@ -0,0 +1,69 @@
+import type { FC, ReactElement } from 'react'
+import { useTranslation } from 'react-i18next'
+import cn from 'classnames'
+import s from './common.module.css'
+import Modal from '@/app/components/base/modal'
+import { XClose } from '@/app/components/base/icons/src/vender/line/general'
+import { AlertCircle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback'
+import Button from '@/app/components/base/button'
+
+type ConfirmCommonProps = {
+  type?: string
+  isShow: boolean
+  onCancel: () => void
+  title: string
+  desc?: string
+  onConfirm: () => void
+}
+
+const ConfirmCommon: FC<ConfirmCommonProps> = ({
+  type = 'danger',
+  isShow,
+  onCancel,
+  title,
+  desc,
+  onConfirm,
+}) => {
+  const { t } = useTranslation()
+
+  const CONFIRM_MAP: Record<string, { icon: ReactElement; confirmText: string }> = {
+    danger: {
+      icon: <AlertCircle className='w-6 h-6 text-[#D92D20]' />,
+      confirmText: t('common.operation.remove'),
+    },
+  }
+
+  return (
+    <Modal isShow={isShow} onClose={() => {}} className='!w-[480px] !max-w-[480px] !p-0 !rounded-2xl'>
+      <div className={cn(s.wrapper, 'relative p-8')}>
+        <div className='flex items-center justify-center absolute top-4 right-4 w-8 h-8 cursor-pointer' onClick={onCancel}>
+          <XClose className='w-4 h-4 text-gray-500' />
+        </div>
+        <div className='flex items-center justify-center mb-3 w-12 h-12 bg-white shadow-xl rounded-xl'>
+          {CONFIRM_MAP[type].icon}
+        </div>
+        <div className='text-xl font-semibold text-gray-900'>{title}</div>
+        {
+          desc && <div className='mt-1 text-sm text-gray-500'>{desc}</div>
+        }
+        <div className='flex items-center justify-end mt-10'>
+          <Button
+            className='mr-2 min-w-24 text-sm font-medium !text-gray-700'
+            onClick={onCancel}
+          >
+            {t('common.operation.cancel')}
+          </Button>
+          <Button
+            type='primary'
+            className=''
+            onClick={onConfirm}
+          >
+            {CONFIRM_MAP[type].confirmText}
+          </Button>
+        </div>
+      </div>
+    </Modal>
+  )
+}
+
+export default ConfirmCommon

BIN
web/app/components/base/icons/assets/image/llm/minimax-text.png


BIN
web/app/components/base/icons/assets/image/llm/minimax.png


BIN
web/app/components/base/icons/assets/image/llm/tongyi-text-cn.png


BIN
web/app/components/base/icons/assets/image/llm/tongyi-text.png


BIN
web/app/components/base/icons/assets/image/llm/tongyi.png


BIN
web/app/components/base/icons/assets/image/llm/wxyy-text-cn.png


BIN
web/app/components/base/icons/assets/image/llm/wxyy-text.png


BIN
web/app/components/base/icons/assets/image/llm/wxyy.png


+ 78 - 0
web/app/components/base/icons/assets/public/llm/anthropic-text.svg

@@ -0,0 +1,78 @@
+<svg width="90" height="20" viewBox="0 0 90 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_8587_60274)">
+<mask id="mask0_8587_60274" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="4" width="90" height="11">
+<path d="M89.375 4.99805H0V14.998H89.375V4.99805Z" fill="white"/>
+</mask>
+<g mask="url(#mask0_8587_60274)">
+<mask id="mask1_8587_60274" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="4" width="90" height="11">
+<path d="M0 4.99609H89.375V14.9961H0V4.99609Z" fill="white"/>
+</mask>
+<g mask="url(#mask1_8587_60274)">
+<mask id="mask2_8587_60274" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="4" width="90" height="11">
+<path d="M0 4.99414H89.375V14.9941H0V4.99414Z" fill="white"/>
+</mask>
+<g mask="url(#mask2_8587_60274)">
+<mask id="mask3_8587_60274" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="4" width="90" height="11">
+<path d="M0 4.99219H89.375V14.9922H0V4.99219Z" fill="white"/>
+</mask>
+<g mask="url(#mask3_8587_60274)">
+<path d="M18.1273 11.9244L13.7773 5.15625H11.4297V14.825H13.4321V8.05688L17.7821 14.825H20.1297V5.15625H18.1273V11.9244Z" fill="black" fill-opacity="0.92"/>
+</g>
+<mask id="mask4_8587_60274" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="4" width="90" height="11">
+<path d="M0 4.99219H89.375V14.9922H0V4.99219Z" fill="white"/>
+</mask>
+<g mask="url(#mask4_8587_60274)">
+<path d="M21.7969 7.02094H25.0423V14.825H27.1139V7.02094H30.3594V5.15625H21.7969V7.02094Z" fill="black" fill-opacity="0.92"/>
+</g>
+<mask id="mask5_8587_60274" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="4" width="90" height="11">
+<path d="M0 4.99219H89.375V14.9922H0V4.99219Z" fill="white"/>
+</mask>
+<g mask="url(#mask5_8587_60274)">
+<path d="M38.6442 9.00994H34.0871V5.15625H32.0156V14.825H34.0871V10.8746H38.6442V14.825H40.7156V5.15625H38.6442V9.00994Z" fill="black" fill-opacity="0.92"/>
+</g>
+<mask id="mask6_8587_60274" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="4" width="90" height="11">
+<path d="M0 4.99219H89.375V14.9922H0V4.99219Z" fill="white"/>
+</mask>
+<g mask="url(#mask6_8587_60274)">
+<path d="M45.3376 7.02094H47.893C48.9152 7.02094 49.4539 7.39387 49.4539 8.09831C49.4539 8.80275 48.9152 9.17569 47.893 9.17569H45.3376V7.02094ZM51.5259 8.09831C51.5259 6.27506 50.186 5.15625 47.9897 5.15625H43.2656V14.825H45.3376V11.0404H47.6443L49.7164 14.825H52.0094L49.715 10.7521C50.8666 10.3094 51.5259 9.37721 51.5259 8.09831Z" fill="black" fill-opacity="0.92"/>
+</g>
+<mask id="mask7_8587_60274" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="4" width="90" height="11">
+<path d="M0 4.99219H89.375V14.9922H0V4.99219Z" fill="white"/>
+</mask>
+<g mask="url(#mask7_8587_60274)">
+<path d="M57.8732 13.0565C56.2438 13.0565 55.2496 11.8963 55.2496 10.004C55.2496 8.08416 56.2438 6.92394 57.8732 6.92394C59.4887 6.92394 60.4691 8.08416 60.4691 10.004C60.4691 11.8963 59.4887 13.0565 57.8732 13.0565ZM57.8732 4.99023C55.0839 4.99023 53.1094 7.06206 53.1094 10.004C53.1094 12.9184 55.0839 14.9902 57.8732 14.9902C60.6486 14.9902 62.6094 12.9184 62.6094 10.004C62.6094 7.06206 60.6486 4.99023 57.8732 4.99023Z" fill="black" fill-opacity="0.92"/>
+</g>
+<mask id="mask8_8587_60274" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="4" width="90" height="11">
+<path d="M0 4.99219H89.375V14.9922H0V4.99219Z" fill="white"/>
+</mask>
+<g mask="url(#mask8_8587_60274)">
+<path d="M69.1794 9.45194H66.6233V7.02094H69.1794C70.2019 7.02094 70.7407 7.43532 70.7407 8.23644C70.7407 9.03756 70.2019 9.45194 69.1794 9.45194ZM69.2762 5.15625H64.5508V14.825H66.6233V11.3166H69.2762C71.473 11.3166 72.8133 10.1564 72.8133 8.23644C72.8133 6.3165 71.473 5.15625 69.2762 5.15625Z" fill="black" fill-opacity="0.92"/>
+</g>
+<mask id="mask9_8587_60274" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="4" width="90" height="11">
+<path d="M0 4.99219H89.375V14.9922H0V4.99219Z" fill="white"/>
+</mask>
+<g mask="url(#mask9_8587_60274)">
+<path d="M86.8413 11.5786C86.4823 12.5179 85.7642 13.0565 84.7837 13.0565C83.1542 13.0565 82.16 11.8963 82.16 10.004C82.16 8.08416 83.1542 6.92394 84.7837 6.92394C85.7642 6.92394 86.4823 7.46261 86.8413 8.40183H89.0369C88.4984 6.33002 86.8827 4.99023 84.7837 4.99023C81.9942 4.99023 80.0195 7.06206 80.0195 10.004C80.0195 12.9184 81.9942 14.9902 84.7837 14.9902C86.8965 14.9902 88.5122 13.6366 89.0508 11.5786H86.8413Z" fill="black" fill-opacity="0.92"/>
+</g>
+<mask id="mask10_8587_60274" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="4" width="90" height="11">
+<path d="M0 4.99219H89.375V14.9922H0V4.99219Z" fill="white"/>
+</mask>
+<g mask="url(#mask10_8587_60274)">
+<path d="M73.6484 5.15625L77.5033 14.825H79.6172L75.7624 5.15625H73.6484Z" fill="black" fill-opacity="0.92"/>
+</g>
+<mask id="mask11_8587_60274" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="4" width="90" height="11">
+<path d="M0 4.99219H89.375V14.9922H0V4.99219Z" fill="white"/>
+</mask>
+<g mask="url(#mask11_8587_60274)">
+<path d="M3.64038 10.9989L4.95938 7.60106L6.27838 10.9989H3.64038ZM3.85422 5.15625L0 14.825H2.15505L2.9433 12.7946H6.97558L7.76371 14.825H9.91875L6.06453 5.15625H3.85422Z" fill="black" fill-opacity="0.92"/>
+</g>
+</g>
+</g>
+</g>
+</g>
+<defs>
+<clipPath id="clip0_8587_60274">
+<rect width="89.375" height="10" fill="white" transform="translate(0 5)"/>
+</clipPath>
+</defs>
+</svg>

+ 1 - 9
web/app/components/base/icons/assets/public/llm/anthropic.svg

@@ -1,12 +1,4 @@
 <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
 <rect width="24" height="24" rx="6" fill="#CA9F7B"/>
-<g clip-path="url(#clip0_7672_55906)">
-<path d="M15.3843 6.43457H12.9687L17.3739 17.565H19.7896L15.3843 6.43457ZM8.40522 6.43457L4 17.565H6.4633L7.36417 15.2276H11.9729L12.8737 17.565H15.337L10.9318 6.43457H8.40522ZM8.16104 13.1605L9.66852 9.24883L11.176 13.1605H8.16104Z" fill="#191918"/>
-</g>
-<rect x="0.5" y="0.5" width="23" height="23" rx="5.5" stroke="black" stroke-opacity="0.05"/>
-<defs>
-<clipPath id="clip0_7672_55906">
-<rect width="16" height="11.1304" fill="white" transform="translate(4 6.43457)"/>
-</clipPath>
-</defs>
+<path d="M15.3843 6.43481H12.9687L17.3739 17.5652H19.7896L15.3843 6.43481ZM8.40522 6.43481L4 17.5652H6.4633L7.36417 15.2279H11.9729L12.8737 17.5652H15.337L10.9318 6.43481H8.40522ZM8.16104 13.1607L9.66852 9.24907L11.176 13.1607H8.16104Z" fill="#191918"/>
 </svg>

Datei-Diff unterdrückt, da er zu groß ist
+ 25 - 0
web/app/components/base/icons/assets/public/llm/azure-openai-service-text.svg


Datei-Diff unterdrückt, da er zu groß ist
+ 7 - 0
web/app/components/base/icons/assets/public/llm/azure-openai-service.svg


Datei-Diff unterdrückt, da er zu groß ist
+ 30 - 0
web/app/components/base/icons/assets/public/llm/azureai-text.svg


Datei-Diff unterdrückt, da er zu groß ist
+ 23 - 0
web/app/components/base/icons/assets/public/llm/azureai.svg


Datei-Diff unterdrückt, da er zu groß ist
+ 16 - 0
web/app/components/base/icons/assets/public/llm/chatglm-text.svg


Datei-Diff unterdrückt, da er zu groß ist
+ 9 - 0
web/app/components/base/icons/assets/public/llm/chatglm.svg


Datei-Diff unterdrückt, da er zu groß ist
+ 45 - 0
web/app/components/base/icons/assets/public/llm/huggingface-text-hub.svg


Datei-Diff unterdrückt, da er zu groß ist
+ 42 - 0
web/app/components/base/icons/assets/public/llm/huggingface-text.svg


Datei-Diff unterdrückt, da er zu groß ist
+ 19 - 0
web/app/components/base/icons/assets/public/llm/huggingface.svg


Datei-Diff unterdrückt, da er zu groß ist
+ 11 - 0
web/app/components/base/icons/assets/public/llm/iflytek-spark-text-cn.svg


Datei-Diff unterdrückt, da er zu groß ist
+ 24 - 0
web/app/components/base/icons/assets/public/llm/iflytek-spark-text.svg


Datei-Diff unterdrückt, da er zu groß ist
+ 5 - 0
web/app/components/base/icons/assets/public/llm/iflytek-spark.svg


+ 8 - 0
web/app/components/base/icons/assets/public/llm/microsoft.svg

@@ -0,0 +1,8 @@
+<svg width="21" height="22" viewBox="0 0 21 22" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="Microsfot">
+<rect id="Rectangle 1010" y="0.5" width="10" height="10" fill="#EF4F21"/>
+<rect id="Rectangle 1012" y="11.5" width="10" height="10" fill="#03A4EE"/>
+<rect id="Rectangle 1011" x="11" y="0.5" width="10" height="10" fill="#7EB903"/>
+<rect id="Rectangle 1013" x="11" y="11.5" width="10" height="10" fill="#FBB604"/>
+</g>
+</svg>

Datei-Diff unterdrückt, da er zu groß ist
+ 4 - 0
web/app/components/base/icons/assets/public/llm/openai-black.svg


Datei-Diff unterdrückt, da er zu groß ist
+ 4 - 0
web/app/components/base/icons/assets/public/llm/openai-blue.svg


Datei-Diff unterdrückt, da er zu groß ist
+ 4 - 0
web/app/components/base/icons/assets/public/llm/openai-green.svg


Datei-Diff unterdrückt, da er zu groß ist
+ 8 - 0
web/app/components/base/icons/assets/public/llm/openai-text.svg


Datei-Diff unterdrückt, da er zu groß ist
+ 3 - 0
web/app/components/base/icons/assets/public/llm/openai-transparent.svg


Datei-Diff unterdrückt, da er zu groß ist
+ 4 - 0
web/app/components/base/icons/assets/public/llm/openai-violet.svg


Datei-Diff unterdrückt, da er zu groß ist
+ 13 - 0
web/app/components/base/icons/assets/public/llm/replicate-text.svg


+ 4 - 0
web/app/components/base/icons/assets/public/llm/replicate.svg

@@ -0,0 +1,4 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<rect width="24" height="24" rx="6" fill="black"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M19.9961 4V5.79H7.93621V19.9017H6V4H19.9961ZM20 7.39453V9.18453H11.5969V19.9012H9.65906V7.39453H20ZM19.9964 12.5773V10.7773H13.3106V19.9007H15.2484V12.5773H19.9964Z" fill="white"/>
+</svg>

+ 5 - 0
web/app/components/base/icons/assets/vender/line/alertsAndFeedback/alert-circle.svg

@@ -0,0 +1,5 @@
+<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="Error">
+<path id="Icon" d="M7.99992 5.83337V8.50004M7.99992 11.1667H8.00659M14.6666 8.50004C14.6666 12.1819 11.6818 15.1667 7.99992 15.1667C4.31802 15.1667 1.33325 12.1819 1.33325 8.50004C1.33325 4.81814 4.31802 1.83337 7.99992 1.83337C11.6818 1.83337 14.6666 4.81814 14.6666 8.50004Z" stroke="#F04438" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+</svg>

+ 5 - 0
web/app/components/base/icons/assets/vender/line/arrows/chevron-down-double.svg

@@ -0,0 +1,5 @@
+<svg width="12" height="13" viewBox="0 0 12 13" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="chevron-down-double">
+<path id="Icon" d="M3.5 7L6 9.5L8.5 7M3.5 3.5L6 6L8.5 3.5" stroke="#667085" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+</svg>

Datei-Diff unterdrückt, da er zu groß ist
+ 10 - 0
web/app/components/base/icons/assets/vender/line/general/at-sign.svg


+ 9 - 0
web/app/components/base/icons/assets/vender/line/general/dots-horizontal.svg

@@ -0,0 +1,9 @@
+<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="Icon">
+<g id="Icon_2">
+<path d="M6 6.5C6.27614 6.5 6.5 6.27614 6.5 6C6.5 5.72386 6.27614 5.5 6 5.5C5.72386 5.5 5.5 5.72386 5.5 6C5.5 6.27614 5.72386 6.5 6 6.5Z" stroke="#344054" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M9.5 6.5C9.77614 6.5 10 6.27614 10 6C10 5.72386 9.77614 5.5 9.5 5.5C9.22386 5.5 9 5.72386 9 6C9 6.27614 9.22386 6.5 9.5 6.5Z" stroke="#344054" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M2.5 6.5C2.77614 6.5 3 6.27614 3 6C3 5.72386 2.77614 5.5 2.5 5.5C2.22386 5.5 2 5.72386 2 6C2 6.27614 2.22386 6.5 2.5 6.5Z" stroke="#344054" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+</g>
+</svg>

Datei-Diff unterdrückt, da er zu groß ist
+ 3 - 0
web/app/components/base/icons/assets/vender/line/general/help-circle.svg


+ 10 - 0
web/app/components/base/icons/assets/vender/line/general/info-circle.svg

@@ -0,0 +1,10 @@
+<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="info-circle" clip-path="url(#clip0_7880_62014)">
+<path id="Icon" d="M6 8V6M6 4H6.005M11 6C11 8.76142 8.76142 11 6 11C3.23858 11 1 8.76142 1 6C1 3.23858 3.23858 1 6 1C8.76142 1 11 3.23858 11 6Z" stroke="#98A2B3" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+<defs>
+<clipPath id="clip0_7880_62014">
+<rect width="12" height="12" fill="white"/>
+</clipPath>
+</defs>
+</svg>

+ 5 - 0
web/app/components/base/icons/assets/vender/line/general/plus.svg

@@ -0,0 +1,5 @@
+<svg width="16" height="17" viewBox="0 0 16 17" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="plus">
+<path id="Icon" d="M8.00004 3.83337V13.1667M3.33337 8.50004H12.6667" stroke="#667085" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+</svg>

+ 5 - 0
web/app/components/base/icons/assets/vender/line/general/search-lg.svg

@@ -0,0 +1,5 @@
+<svg width="14" height="15" viewBox="0 0 14 15" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="Icon">
+<path id="Icon_2" d="M12.25 12.75L10.2084 10.7083M11.6667 7.20833C11.6667 9.94675 9.44675 12.1667 6.70833 12.1667C3.96992 12.1667 1.75 9.94675 1.75 7.20833C1.75 4.46992 3.96992 2.25 6.70833 2.25C9.44675 2.25 11.6667 4.46992 11.6667 7.20833Z" stroke="#98A2B3" stroke-width="1.25" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+</svg>

Datei-Diff unterdrückt, da er zu groß ist
+ 10 - 0
web/app/components/base/icons/assets/vender/line/mapsAndTravel/globe-01.svg


Datei-Diff unterdrückt, da er zu groß ist
+ 13 - 0
web/app/components/base/icons/assets/vender/line/shapes/cube-outline.svg


Datei-Diff unterdrückt, da er zu groß ist
+ 5 - 0
web/app/components/base/icons/assets/vender/line/users/user-01.svg


Datei-Diff unterdrückt, da er zu groß ist
+ 5 - 0
web/app/components/base/icons/assets/vender/line/users/users-01.svg


Datei-Diff unterdrückt, da er zu groß ist
+ 5 - 0
web/app/components/base/icons/assets/vender/solid/FinanceAndECommerce/scales-02.svg


Datei-Diff unterdrückt, da er zu groß ist
+ 4 - 0
web/app/components/base/icons/assets/vender/solid/editor/brush-01.svg


Datei-Diff unterdrückt, da er zu groß ist
+ 5 - 0
web/app/components/base/icons/assets/vender/solid/general/target-04.svg


+ 8 - 0
web/app/components/base/icons/assets/vender/solid/mediaAndDevices/sliders-02.svg

@@ -0,0 +1,8 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M5 2C5.55228 2 6 2.44772 6 3V7C6 7.55228 5.55228 8 5 8C4.44772 8 4 7.55228 4 7V3C4 2.44772 4.44772 2 5 2Z" fill="black"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M6 15.8293C7.16519 15.4175 8 14.3062 8 13C8 11.3431 6.65685 10 5 10C3.34315 10 2 11.3431 2 13C2 14.3062 2.83481 15.4175 4 15.8293L4 21C4 21.5523 4.44772 22 5 22C5.55229 22 6 21.5523 6 21L6 15.8293Z" fill="black"/>
+<path d="M13 15C13 14.4477 12.5523 14 12 14C11.4477 14 11 14.4477 11 15V21C11 21.5523 11.4477 22 12 22C12.5523 22 13 21.5523 13 21V15Z" fill="black"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M12 2C12.5523 2 13 2.44772 13 3V6.17071C14.1652 6.58254 15 7.69378 15 9C15 10.6569 13.6569 12 12 12C10.3431 12 9 10.6569 9 9C9 7.69378 9.83481 6.58254 11 6.17071V3C11 2.44772 11.4477 2 12 2Z" fill="black"/>
+<path fill-rule="evenodd" clip-rule="evenodd" d="M22 15C22 16.3062 21.1652 17.4175 20 17.8293V21C20 21.5523 19.5523 22 19 22C18.4477 22 18 21.5523 18 21V17.8293C16.8348 17.4175 16 16.3062 16 15C16 13.3431 17.3431 12 19 12C20.6569 12 22 13.3431 22 15Z" fill="black"/>
+<path d="M19 2C19.5523 2 20 2.44772 20 3V9C20 9.55228 19.5523 10 19 10C18.4477 10 18 9.55228 18 9V3C18 2.44772 18.4477 2 19 2Z" fill="black"/>
+</svg>

Datei-Diff unterdrückt, da er zu groß ist
+ 5 - 0
web/app/components/base/icons/assets/vender/solid/security/lock-01.svg


Datei-Diff unterdrückt, da er zu groß ist
+ 8 - 0
web/app/components/base/icons/assets/vender/solid/users/user-01.svg


Datei-Diff unterdrückt, da er zu groß ist
+ 10 - 0
web/app/components/base/icons/assets/vender/solid/users/users-01.svg


+ 52 - 0
web/app/components/base/icons/script.js

@@ -77,6 +77,54 @@ export { default as <%= svgName %> } from './<%= svgName %>'
   await appendFile(path.resolve(currentPath, 'index.ts'), `${indexingRender({ svgName: fileName })}\n`)
 }
 
+const generateImageComponent = async (entry, pathList) => {
+  const currentPath = path.resolve(__dirname, 'src', ...pathList.slice(2))
+
+  try {
+    await access(currentPath)
+  }
+  catch {
+    await generateDir(currentPath)
+  }
+
+  const prefixFileName = camelCase(entry.split('.')[0])
+  const fileName = prefixFileName.charAt(0).toUpperCase() + prefixFileName.slice(1)
+
+  const componentCSSRender = template(`
+.wrapper {
+  display: inline-flex;
+  background: url(<%= assetPath %>) center center no-repeat;
+  background-size: contain;
+}
+`.trim())
+
+  await writeFile(path.resolve(currentPath, `${fileName}.module.css`), `${componentCSSRender({ assetPath: path.join('~@/app/components/base/icons/assets', ...pathList.slice(2), entry) })}\n`)
+
+  const componentRender = template(`
+// GENERATE BY script
+// DON NOT EDIT IT MANUALLY
+
+import * as React from 'react'
+import cn from 'classnames'
+import s from './<%= fileName %>.module.css'
+
+const Icon = React.forwardRef<HTMLSpanElement, React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>>((
+  { className, ...restProps },
+  ref,
+) => <span className={cn(s.wrapper, className)} {...restProps} ref={ref} />)
+
+export default Icon
+`.trim())
+
+  await writeFile(path.resolve(currentPath, `${fileName}.tsx`), `${componentRender({ fileName })}\n`)
+
+  const indexingRender = template(`
+export { default as <%= fileName %> } from './<%= fileName %>'
+`.trim())
+
+  await appendFile(path.resolve(currentPath, 'index.ts'), `${indexingRender({ fileName })}\n`)
+}
+
 const walk = async (entry, pathList, replaceFillOrStrokeColor) => {
   const currentPath = path.resolve(...pathList, entry)
   let fileHandle
@@ -94,6 +142,9 @@ const walk = async (entry, pathList, replaceFillOrStrokeColor) => {
 
     if (stat.isFile() && /.+\.svg$/g.test(entry))
       await generateSvgComponent(fileHandle, entry, pathList, replaceFillOrStrokeColor)
+
+    if (stat.isFile() && /.+\.png$/g.test(entry))
+      await generateImageComponent(entry, pathList)
   }
   finally {
     fileHandle?.close()
@@ -104,4 +155,5 @@ const walk = async (entry, pathList, replaceFillOrStrokeColor) => {
   await rm(path.resolve(__dirname, 'src'), { recursive: true, force: true })
   await walk('public', [__dirname, 'assets'])
   await walk('vender', [__dirname, 'assets'], true)
+  await walk('image', [__dirname, 'assets'])
 })()

+ 5 - 0
web/app/components/base/icons/src/image/llm/Minimax.module.css

@@ -0,0 +1,5 @@
+.wrapper {
+  display: inline-flex;
+  background: url(~@/app/components/base/icons/assets/image/llm/minimax.png) center center no-repeat;
+  background-size: contain;
+}

+ 13 - 0
web/app/components/base/icons/src/image/llm/Minimax.tsx

@@ -0,0 +1,13 @@
+// GENERATE BY script
+// DON NOT EDIT IT MANUALLY
+
+import * as React from 'react'
+import cn from 'classnames'
+import s from './Minimax.module.css'
+
+const Icon = React.forwardRef<HTMLSpanElement, React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>>((
+  { className, ...restProps },
+  ref,
+) => <span className={cn(s.wrapper, className)} {...restProps} ref={ref} />)
+
+export default Icon

+ 5 - 0
web/app/components/base/icons/src/image/llm/MinimaxText.module.css

@@ -0,0 +1,5 @@
+.wrapper {
+  display: inline-flex;
+  background: url(~@/app/components/base/icons/assets/image/llm/minimax-text.png) center center no-repeat;
+  background-size: contain;
+}

+ 13 - 0
web/app/components/base/icons/src/image/llm/MinimaxText.tsx

@@ -0,0 +1,13 @@
+// GENERATE BY script
+// DON NOT EDIT IT MANUALLY
+
+import * as React from 'react'
+import cn from 'classnames'
+import s from './MinimaxText.module.css'
+
+const Icon = React.forwardRef<HTMLSpanElement, React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>>((
+  { className, ...restProps },
+  ref,
+) => <span className={cn(s.wrapper, className)} {...restProps} ref={ref} />)
+
+export default Icon

+ 5 - 0
web/app/components/base/icons/src/image/llm/Tongyi.module.css

@@ -0,0 +1,5 @@
+.wrapper {
+  display: inline-flex;
+  background: url(~@/app/components/base/icons/assets/image/llm/tongyi.png) center center no-repeat;
+  background-size: contain;
+}

+ 13 - 0
web/app/components/base/icons/src/image/llm/Tongyi.tsx

@@ -0,0 +1,13 @@
+// GENERATE BY script
+// DON NOT EDIT IT MANUALLY
+
+import * as React from 'react'
+import cn from 'classnames'
+import s from './Tongyi.module.css'
+
+const Icon = React.forwardRef<HTMLSpanElement, React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>>((
+  { className, ...restProps },
+  ref,
+) => <span className={cn(s.wrapper, className)} {...restProps} ref={ref} />)
+
+export default Icon

+ 5 - 0
web/app/components/base/icons/src/image/llm/TongyiText.module.css

@@ -0,0 +1,5 @@
+.wrapper {
+  display: inline-flex;
+  background: url(~@/app/components/base/icons/assets/image/llm/tongyi-text.png) center center no-repeat;
+  background-size: contain;
+}

+ 13 - 0
web/app/components/base/icons/src/image/llm/TongyiText.tsx

@@ -0,0 +1,13 @@
+// GENERATE BY script
+// DON NOT EDIT IT MANUALLY
+
+import * as React from 'react'
+import cn from 'classnames'
+import s from './TongyiText.module.css'
+
+const Icon = React.forwardRef<HTMLSpanElement, React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>>((
+  { className, ...restProps },
+  ref,
+) => <span className={cn(s.wrapper, className)} {...restProps} ref={ref} />)
+
+export default Icon

+ 5 - 0
web/app/components/base/icons/src/image/llm/TongyiTextCn.module.css

@@ -0,0 +1,5 @@
+.wrapper {
+  display: inline-flex;
+  background: url(~@/app/components/base/icons/assets/image/llm/tongyi-text-cn.png) center center no-repeat;
+  background-size: contain;
+}

+ 13 - 0
web/app/components/base/icons/src/image/llm/TongyiTextCn.tsx

@@ -0,0 +1,13 @@
+// GENERATE BY script
+// DON NOT EDIT IT MANUALLY
+
+import * as React from 'react'
+import cn from 'classnames'
+import s from './TongyiTextCn.module.css'
+
+const Icon = React.forwardRef<HTMLSpanElement, React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>>((
+  { className, ...restProps },
+  ref,
+) => <span className={cn(s.wrapper, className)} {...restProps} ref={ref} />)
+
+export default Icon

+ 5 - 0
web/app/components/base/icons/src/image/llm/Wxyy.module.css

@@ -0,0 +1,5 @@
+.wrapper {
+  display: inline-flex;
+  background: url(~@/app/components/base/icons/assets/image/llm/wxyy.png) center center no-repeat;
+  background-size: contain;
+}

+ 13 - 0
web/app/components/base/icons/src/image/llm/Wxyy.tsx

@@ -0,0 +1,13 @@
+// GENERATE BY script
+// DON NOT EDIT IT MANUALLY
+
+import * as React from 'react'
+import cn from 'classnames'
+import s from './Wxyy.module.css'
+
+const Icon = React.forwardRef<HTMLSpanElement, React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>>((
+  { className, ...restProps },
+  ref,
+) => <span className={cn(s.wrapper, className)} {...restProps} ref={ref} />)
+
+export default Icon

+ 5 - 0
web/app/components/base/icons/src/image/llm/WxyyText.module.css

@@ -0,0 +1,5 @@
+.wrapper {
+  display: inline-flex;
+  background: url(~@/app/components/base/icons/assets/image/llm/wxyy-text.png) center center no-repeat;
+  background-size: contain;
+}

+ 13 - 0
web/app/components/base/icons/src/image/llm/WxyyText.tsx

@@ -0,0 +1,13 @@
+// GENERATE BY script
+// DON NOT EDIT IT MANUALLY
+
+import * as React from 'react'
+import cn from 'classnames'
+import s from './WxyyText.module.css'
+
+const Icon = React.forwardRef<HTMLSpanElement, React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>>((
+  { className, ...restProps },
+  ref,
+) => <span className={cn(s.wrapper, className)} {...restProps} ref={ref} />)
+
+export default Icon

+ 5 - 0
web/app/components/base/icons/src/image/llm/WxyyTextCn.module.css

@@ -0,0 +1,5 @@
+.wrapper {
+  display: inline-flex;
+  background: url(~@/app/components/base/icons/assets/image/llm/wxyy-text-cn.png) center center no-repeat;
+  background-size: contain;
+}

+ 13 - 0
web/app/components/base/icons/src/image/llm/WxyyTextCn.tsx

@@ -0,0 +1,13 @@
+// GENERATE BY script
+// DON NOT EDIT IT MANUALLY
+
+import * as React from 'react'
+import cn from 'classnames'
+import s from './WxyyTextCn.module.css'
+
+const Icon = React.forwardRef<HTMLSpanElement, React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement>>((
+  { className, ...restProps },
+  ref,
+) => <span className={cn(s.wrapper, className)} {...restProps} ref={ref} />)
+
+export default Icon

+ 8 - 0
web/app/components/base/icons/src/image/llm/index.ts

@@ -0,0 +1,8 @@
+export { default as MinimaxText } from './MinimaxText'
+export { default as Minimax } from './Minimax'
+export { default as TongyiTextCn } from './TongyiTextCn'
+export { default as TongyiText } from './TongyiText'
+export { default as Tongyi } from './Tongyi'
+export { default as WxyyTextCn } from './WxyyTextCn'
+export { default as WxyyText } from './WxyyText'
+export { default as Wxyy } from './Wxyy'

+ 3 - 53
web/app/components/base/icons/src/public/llm/Anthropic.json

@@ -24,62 +24,12 @@
 			},
 			{
 				"type": "element",
-				"name": "g",
+				"name": "path",
 				"attributes": {
-					"clip-path": "url(#clip0_7672_55906)"
-				},
-				"children": [
-					{
-						"type": "element",
-						"name": "path",
-						"attributes": {
-							"d": "M15.3843 6.43457H12.9687L17.3739 17.565H19.7896L15.3843 6.43457ZM8.40522 6.43457L4 17.565H6.4633L7.36417 15.2276H11.9729L12.8737 17.565H15.337L10.9318 6.43457H8.40522ZM8.16104 13.1605L9.66852 9.24883L11.176 13.1605H8.16104Z",
-							"fill": "#191918"
-						},
-						"children": []
-					}
-				]
-			},
-			{
-				"type": "element",
-				"name": "rect",
-				"attributes": {
-					"x": "0.5",
-					"y": "0.5",
-					"width": "23",
-					"height": "23",
-					"rx": "5.5",
-					"stroke": "black",
-					"stroke-opacity": "0.05"
+					"d": "M15.3843 6.43481H12.9687L17.3739 17.5652H19.7896L15.3843 6.43481ZM8.40522 6.43481L4 17.5652H6.4633L7.36417 15.2279H11.9729L12.8737 17.5652H15.337L10.9318 6.43481H8.40522ZM8.16104 13.1607L9.66852 9.24907L11.176 13.1607H8.16104Z",
+					"fill": "#191918"
 				},
 				"children": []
-			},
-			{
-				"type": "element",
-				"name": "defs",
-				"attributes": {},
-				"children": [
-					{
-						"type": "element",
-						"name": "clipPath",
-						"attributes": {
-							"id": "clip0_7672_55906"
-						},
-						"children": [
-							{
-								"type": "element",
-								"name": "rect",
-								"attributes": {
-									"width": "16",
-									"height": "11.1304",
-									"fill": "white",
-									"transform": "translate(4 6.43457)"
-								},
-								"children": []
-							}
-						]
-					}
-				]
 			}
 		]
 	},

+ 539 - 0
web/app/components/base/icons/src/public/llm/AnthropicText.json

@@ -0,0 +1,539 @@
+{
+	"icon": {
+		"type": "element",
+		"isRootNode": true,
+		"name": "svg",
+		"attributes": {
+			"width": "90",
+			"height": "20",
+			"viewBox": "0 0 90 20",
+			"fill": "none",
+			"xmlns": "http://www.w3.org/2000/svg"
+		},
+		"children": [
+			{
+				"type": "element",
+				"name": "g",
+				"attributes": {
+					"clip-path": "url(#clip0_8587_60274)"
+				},
+				"children": [
+					{
+						"type": "element",
+						"name": "mask",
+						"attributes": {
+							"id": "mask0_8587_60274",
+							"style": "mask-type:luminance",
+							"maskUnits": "userSpaceOnUse",
+							"x": "0",
+							"y": "4",
+							"width": "90",
+							"height": "11"
+						},
+						"children": [
+							{
+								"type": "element",
+								"name": "path",
+								"attributes": {
+									"d": "M89.375 4.99805H0V14.998H89.375V4.99805Z",
+									"fill": "white"
+								},
+								"children": []
+							}
+						]
+					},
+					{
+						"type": "element",
+						"name": "g",
+						"attributes": {
+							"mask": "url(#mask0_8587_60274)"
+						},
+						"children": [
+							{
+								"type": "element",
+								"name": "mask",
+								"attributes": {
+									"id": "mask1_8587_60274",
+									"style": "mask-type:luminance",
+									"maskUnits": "userSpaceOnUse",
+									"x": "0",
+									"y": "4",
+									"width": "90",
+									"height": "11"
+								},
+								"children": [
+									{
+										"type": "element",
+										"name": "path",
+										"attributes": {
+											"d": "M0 4.99609H89.375V14.9961H0V4.99609Z",
+											"fill": "white"
+										},
+										"children": []
+									}
+								]
+							},
+							{
+								"type": "element",
+								"name": "g",
+								"attributes": {
+									"mask": "url(#mask1_8587_60274)"
+								},
+								"children": [
+									{
+										"type": "element",
+										"name": "mask",
+										"attributes": {
+											"id": "mask2_8587_60274",
+											"style": "mask-type:luminance",
+											"maskUnits": "userSpaceOnUse",
+											"x": "0",
+											"y": "4",
+											"width": "90",
+											"height": "11"
+										},
+										"children": [
+											{
+												"type": "element",
+												"name": "path",
+												"attributes": {
+													"d": "M0 4.99414H89.375V14.9941H0V4.99414Z",
+													"fill": "white"
+												},
+												"children": []
+											}
+										]
+									},
+									{
+										"type": "element",
+										"name": "g",
+										"attributes": {
+											"mask": "url(#mask2_8587_60274)"
+										},
+										"children": [
+											{
+												"type": "element",
+												"name": "mask",
+												"attributes": {
+													"id": "mask3_8587_60274",
+													"style": "mask-type:luminance",
+													"maskUnits": "userSpaceOnUse",
+													"x": "0",
+													"y": "4",
+													"width": "90",
+													"height": "11"
+												},
+												"children": [
+													{
+														"type": "element",
+														"name": "path",
+														"attributes": {
+															"d": "M0 4.99219H89.375V14.9922H0V4.99219Z",
+															"fill": "white"
+														},
+														"children": []
+													}
+												]
+											},
+											{
+												"type": "element",
+												"name": "g",
+												"attributes": {
+													"mask": "url(#mask3_8587_60274)"
+												},
+												"children": [
+													{
+														"type": "element",
+														"name": "path",
+														"attributes": {
+															"d": "M18.1273 11.9244L13.7773 5.15625H11.4297V14.825H13.4321V8.05688L17.7821 14.825H20.1297V5.15625H18.1273V11.9244Z",
+															"fill": "black",
+															"fill-opacity": "0.92"
+														},
+														"children": []
+													}
+												]
+											},
+											{
+												"type": "element",
+												"name": "mask",
+												"attributes": {
+													"id": "mask4_8587_60274",
+													"style": "mask-type:luminance",
+													"maskUnits": "userSpaceOnUse",
+													"x": "0",
+													"y": "4",
+													"width": "90",
+													"height": "11"
+												},
+												"children": [
+													{
+														"type": "element",
+														"name": "path",
+														"attributes": {
+															"d": "M0 4.99219H89.375V14.9922H0V4.99219Z",
+															"fill": "white"
+														},
+														"children": []
+													}
+												]
+											},
+											{
+												"type": "element",
+												"name": "g",
+												"attributes": {
+													"mask": "url(#mask4_8587_60274)"
+												},
+												"children": [
+													{
+														"type": "element",
+														"name": "path",
+														"attributes": {
+															"d": "M21.7969 7.02094H25.0423V14.825H27.1139V7.02094H30.3594V5.15625H21.7969V7.02094Z",
+															"fill": "black",
+															"fill-opacity": "0.92"
+														},
+														"children": []
+													}
+												]
+											},
+											{
+												"type": "element",
+												"name": "mask",
+												"attributes": {
+													"id": "mask5_8587_60274",
+													"style": "mask-type:luminance",
+													"maskUnits": "userSpaceOnUse",
+													"x": "0",
+													"y": "4",
+													"width": "90",
+													"height": "11"
+												},
+												"children": [
+													{
+														"type": "element",
+														"name": "path",
+														"attributes": {
+															"d": "M0 4.99219H89.375V14.9922H0V4.99219Z",
+															"fill": "white"
+														},
+														"children": []
+													}
+												]
+											},
+											{
+												"type": "element",
+												"name": "g",
+												"attributes": {
+													"mask": "url(#mask5_8587_60274)"
+												},
+												"children": [
+													{
+														"type": "element",
+														"name": "path",
+														"attributes": {
+															"d": "M38.6442 9.00994H34.0871V5.15625H32.0156V14.825H34.0871V10.8746H38.6442V14.825H40.7156V5.15625H38.6442V9.00994Z",
+															"fill": "black",
+															"fill-opacity": "0.92"
+														},
+														"children": []
+													}
+												]
+											},
+											{
+												"type": "element",
+												"name": "mask",
+												"attributes": {
+													"id": "mask6_8587_60274",
+													"style": "mask-type:luminance",
+													"maskUnits": "userSpaceOnUse",
+													"x": "0",
+													"y": "4",
+													"width": "90",
+													"height": "11"
+												},
+												"children": [
+													{
+														"type": "element",
+														"name": "path",
+														"attributes": {
+															"d": "M0 4.99219H89.375V14.9922H0V4.99219Z",
+															"fill": "white"
+														},
+														"children": []
+													}
+												]
+											},
+											{
+												"type": "element",
+												"name": "g",
+												"attributes": {
+													"mask": "url(#mask6_8587_60274)"
+												},
+												"children": [
+													{
+														"type": "element",
+														"name": "path",
+														"attributes": {
+															"d": "M45.3376 7.02094H47.893C48.9152 7.02094 49.4539 7.39387 49.4539 8.09831C49.4539 8.80275 48.9152 9.17569 47.893 9.17569H45.3376V7.02094ZM51.5259 8.09831C51.5259 6.27506 50.186 5.15625 47.9897 5.15625H43.2656V14.825H45.3376V11.0404H47.6443L49.7164 14.825H52.0094L49.715 10.7521C50.8666 10.3094 51.5259 9.37721 51.5259 8.09831Z",
+															"fill": "black",
+															"fill-opacity": "0.92"
+														},
+														"children": []
+													}
+												]
+											},
+											{
+												"type": "element",
+												"name": "mask",
+												"attributes": {
+													"id": "mask7_8587_60274",
+													"style": "mask-type:luminance",
+													"maskUnits": "userSpaceOnUse",
+													"x": "0",
+													"y": "4",
+													"width": "90",
+													"height": "11"
+												},
+												"children": [
+													{
+														"type": "element",
+														"name": "path",
+														"attributes": {
+															"d": "M0 4.99219H89.375V14.9922H0V4.99219Z",
+															"fill": "white"
+														},
+														"children": []
+													}
+												]
+											},
+											{
+												"type": "element",
+												"name": "g",
+												"attributes": {
+													"mask": "url(#mask7_8587_60274)"
+												},
+												"children": [
+													{
+														"type": "element",
+														"name": "path",
+														"attributes": {
+															"d": "M57.8732 13.0565C56.2438 13.0565 55.2496 11.8963 55.2496 10.004C55.2496 8.08416 56.2438 6.92394 57.8732 6.92394C59.4887 6.92394 60.4691 8.08416 60.4691 10.004C60.4691 11.8963 59.4887 13.0565 57.8732 13.0565ZM57.8732 4.99023C55.0839 4.99023 53.1094 7.06206 53.1094 10.004C53.1094 12.9184 55.0839 14.9902 57.8732 14.9902C60.6486 14.9902 62.6094 12.9184 62.6094 10.004C62.6094 7.06206 60.6486 4.99023 57.8732 4.99023Z",
+															"fill": "black",
+															"fill-opacity": "0.92"
+														},
+														"children": []
+													}
+												]
+											},
+											{
+												"type": "element",
+												"name": "mask",
+												"attributes": {
+													"id": "mask8_8587_60274",
+													"style": "mask-type:luminance",
+													"maskUnits": "userSpaceOnUse",
+													"x": "0",
+													"y": "4",
+													"width": "90",
+													"height": "11"
+												},
+												"children": [
+													{
+														"type": "element",
+														"name": "path",
+														"attributes": {
+															"d": "M0 4.99219H89.375V14.9922H0V4.99219Z",
+															"fill": "white"
+														},
+														"children": []
+													}
+												]
+											},
+											{
+												"type": "element",
+												"name": "g",
+												"attributes": {
+													"mask": "url(#mask8_8587_60274)"
+												},
+												"children": [
+													{
+														"type": "element",
+														"name": "path",
+														"attributes": {
+															"d": "M69.1794 9.45194H66.6233V7.02094H69.1794C70.2019 7.02094 70.7407 7.43532 70.7407 8.23644C70.7407 9.03756 70.2019 9.45194 69.1794 9.45194ZM69.2762 5.15625H64.5508V14.825H66.6233V11.3166H69.2762C71.473 11.3166 72.8133 10.1564 72.8133 8.23644C72.8133 6.3165 71.473 5.15625 69.2762 5.15625Z",
+															"fill": "black",
+															"fill-opacity": "0.92"
+														},
+														"children": []
+													}
+												]
+											},
+											{
+												"type": "element",
+												"name": "mask",
+												"attributes": {
+													"id": "mask9_8587_60274",
+													"style": "mask-type:luminance",
+													"maskUnits": "userSpaceOnUse",
+													"x": "0",
+													"y": "4",
+													"width": "90",
+													"height": "11"
+												},
+												"children": [
+													{
+														"type": "element",
+														"name": "path",
+														"attributes": {
+															"d": "M0 4.99219H89.375V14.9922H0V4.99219Z",
+															"fill": "white"
+														},
+														"children": []
+													}
+												]
+											},
+											{
+												"type": "element",
+												"name": "g",
+												"attributes": {
+													"mask": "url(#mask9_8587_60274)"
+												},
+												"children": [
+													{
+														"type": "element",
+														"name": "path",
+														"attributes": {
+															"d": "M86.8413 11.5786C86.4823 12.5179 85.7642 13.0565 84.7837 13.0565C83.1542 13.0565 82.16 11.8963 82.16 10.004C82.16 8.08416 83.1542 6.92394 84.7837 6.92394C85.7642 6.92394 86.4823 7.46261 86.8413 8.40183H89.0369C88.4984 6.33002 86.8827 4.99023 84.7837 4.99023C81.9942 4.99023 80.0195 7.06206 80.0195 10.004C80.0195 12.9184 81.9942 14.9902 84.7837 14.9902C86.8965 14.9902 88.5122 13.6366 89.0508 11.5786H86.8413Z",
+															"fill": "black",
+															"fill-opacity": "0.92"
+														},
+														"children": []
+													}
+												]
+											},
+											{
+												"type": "element",
+												"name": "mask",
+												"attributes": {
+													"id": "mask10_8587_60274",
+													"style": "mask-type:luminance",
+													"maskUnits": "userSpaceOnUse",
+													"x": "0",
+													"y": "4",
+													"width": "90",
+													"height": "11"
+												},
+												"children": [
+													{
+														"type": "element",
+														"name": "path",
+														"attributes": {
+															"d": "M0 4.99219H89.375V14.9922H0V4.99219Z",
+															"fill": "white"
+														},
+														"children": []
+													}
+												]
+											},
+											{
+												"type": "element",
+												"name": "g",
+												"attributes": {
+													"mask": "url(#mask10_8587_60274)"
+												},
+												"children": [
+													{
+														"type": "element",
+														"name": "path",
+														"attributes": {
+															"d": "M73.6484 5.15625L77.5033 14.825H79.6172L75.7624 5.15625H73.6484Z",
+															"fill": "black",
+															"fill-opacity": "0.92"
+														},
+														"children": []
+													}
+												]
+											},
+											{
+												"type": "element",
+												"name": "mask",
+												"attributes": {
+													"id": "mask11_8587_60274",
+													"style": "mask-type:luminance",
+													"maskUnits": "userSpaceOnUse",
+													"x": "0",
+													"y": "4",
+													"width": "90",
+													"height": "11"
+												},
+												"children": [
+													{
+														"type": "element",
+														"name": "path",
+														"attributes": {
+															"d": "M0 4.99219H89.375V14.9922H0V4.99219Z",
+															"fill": "white"
+														},
+														"children": []
+													}
+												]
+											},
+											{
+												"type": "element",
+												"name": "g",
+												"attributes": {
+													"mask": "url(#mask11_8587_60274)"
+												},
+												"children": [
+													{
+														"type": "element",
+														"name": "path",
+														"attributes": {
+															"d": "M3.64038 10.9989L4.95938 7.60106L6.27838 10.9989H3.64038ZM3.85422 5.15625L0 14.825H2.15505L2.9433 12.7946H6.97558L7.76371 14.825H9.91875L6.06453 5.15625H3.85422Z",
+															"fill": "black",
+															"fill-opacity": "0.92"
+														},
+														"children": []
+													}
+												]
+											}
+										]
+									}
+								]
+							}
+						]
+					}
+				]
+			},
+			{
+				"type": "element",
+				"name": "defs",
+				"attributes": {},
+				"children": [
+					{
+						"type": "element",
+						"name": "clipPath",
+						"attributes": {
+							"id": "clip0_8587_60274"
+						},
+						"children": [
+							{
+								"type": "element",
+								"name": "rect",
+								"attributes": {
+									"width": "89.375",
+									"height": "10",
+									"fill": "white",
+									"transform": "translate(0 5)"
+								},
+								"children": []
+							}
+						]
+					}
+				]
+			}
+		]
+	},
+	"name": "AnthropicText"
+}

+ 14 - 0
web/app/components/base/icons/src/public/llm/AnthropicText.tsx

@@ -0,0 +1,14 @@
+// GENERATE BY script
+// DON NOT EDIT IT MANUALLY
+
+import * as React from 'react'
+import data from './AnthropicText.json'
+import IconBase from '@/app/components/base/icons/IconBase'
+import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
+
+const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
+  props,
+  ref,
+) => <IconBase {...props} ref={ref} data={data as IconData} />)
+
+export default Icon

Datei-Diff unterdrückt, da er zu groß ist
+ 74 - 0
web/app/components/base/icons/src/public/llm/AzureOpenaiService.json


+ 14 - 0
web/app/components/base/icons/src/public/llm/AzureOpenaiService.tsx

@@ -0,0 +1,14 @@
+// GENERATE BY script
+// DON NOT EDIT IT MANUALLY
+
+import * as React from 'react'
+import data from './AzureOpenaiService.json'
+import IconBase from '@/app/components/base/icons/IconBase'
+import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
+
+const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
+  props,
+  ref,
+) => <IconBase {...props} ref={ref} data={data as IconData} />)
+
+export default Icon

Datei-Diff unterdrückt, da er zu groß ist
+ 236 - 0
web/app/components/base/icons/src/public/llm/AzureOpenaiServiceText.json


+ 14 - 0
web/app/components/base/icons/src/public/llm/AzureOpenaiServiceText.tsx

@@ -0,0 +1,14 @@
+// GENERATE BY script
+// DON NOT EDIT IT MANUALLY
+
+import * as React from 'react'
+import data from './AzureOpenaiServiceText.json'
+import IconBase from '@/app/components/base/icons/IconBase'
+import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
+
+const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
+  props,
+  ref,
+) => <IconBase {...props} ref={ref} data={data as IconData} />)
+
+export default Icon

Datei-Diff unterdrückt, da er zu groß ist
+ 180 - 0
web/app/components/base/icons/src/public/llm/Azureai.json


+ 14 - 0
web/app/components/base/icons/src/public/llm/Azureai.tsx

@@ -0,0 +1,14 @@
+// GENERATE BY script
+// DON NOT EDIT IT MANUALLY
+
+import * as React from 'react'
+import data from './Azureai.json'
+import IconBase from '@/app/components/base/icons/IconBase'
+import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
+
+const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
+  props,
+  ref,
+) => <IconBase {...props} ref={ref} data={data as IconData} />)
+
+export default Icon

Datei-Diff unterdrückt, da er zu groß ist
+ 243 - 0
web/app/components/base/icons/src/public/llm/AzureaiText.json


+ 14 - 0
web/app/components/base/icons/src/public/llm/AzureaiText.tsx

@@ -0,0 +1,14 @@
+// GENERATE BY script
+// DON NOT EDIT IT MANUALLY
+
+import * as React from 'react'
+import data from './AzureaiText.json'
+import IconBase from '@/app/components/base/icons/IconBase'
+import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
+
+const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
+  props,
+  ref,
+) => <IconBase {...props} ref={ref} data={data as IconData} />)
+
+export default Icon

Datei-Diff unterdrückt, da er zu groß ist
+ 72 - 0
web/app/components/base/icons/src/public/llm/Chatglm.json


+ 14 - 0
web/app/components/base/icons/src/public/llm/Chatglm.tsx

@@ -0,0 +1,14 @@
+// GENERATE BY script
+// DON NOT EDIT IT MANUALLY
+
+import * as React from 'react'
+import data from './Chatglm.json'
+import IconBase from '@/app/components/base/icons/IconBase'
+import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
+
+const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
+  props,
+  ref,
+) => <IconBase {...props} ref={ref} data={data as IconData} />)
+
+export default Icon

Datei-Diff unterdrückt, da er zu groß ist
+ 135 - 0
web/app/components/base/icons/src/public/llm/ChatglmText.json


+ 14 - 0
web/app/components/base/icons/src/public/llm/ChatglmText.tsx

@@ -0,0 +1,14 @@
+// GENERATE BY script
+// DON NOT EDIT IT MANUALLY
+
+import * as React from 'react'
+import data from './ChatglmText.json'
+import IconBase from '@/app/components/base/icons/IconBase'
+import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
+
+const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
+  props,
+  ref,
+) => <IconBase {...props} ref={ref} data={data as IconData} />)
+
+export default Icon

+ 0 - 0
web/app/components/base/icons/src/public/llm/Huggingface.json


Einige Dateien werden nicht angezeigt, da zu viele Dateien in diesem Diff geändert wurden.