mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-01 01:30:51 +08:00
Feature/dmxapi painting add model (#7851)
* 新增图片模型 * 新增图片生成模型 * 新增模型和调整提示语
This commit is contained in:
parent
e5956d4039
commit
53600175b9
@ -1029,7 +1029,7 @@
|
||||
"turbo": "Turbo"
|
||||
},
|
||||
"req_error_no_balance": "Please check the validity of the token",
|
||||
"req_error_text": "Operation failed. Please try again. Avoid using 'copyrighted' or 'sensitive' words in your prompt.",
|
||||
"req_error_text": "The server is busy or the prompt contains \"copyrighted\" or \"sensitive\" terms. Please try again.",
|
||||
"req_error_token": "Please check the validity of the token",
|
||||
"required_field": "Required field",
|
||||
"seed": "Seed",
|
||||
|
||||
@ -1029,7 +1029,7 @@
|
||||
"turbo": "高速"
|
||||
},
|
||||
"req_error_no_balance": "トークンの有効性を確認してください",
|
||||
"req_error_text": "実行に失敗しました。もう一度お試しください。プロンプトに「著作権用語」や「センシティブな用語」を含めないでください。",
|
||||
"req_error_text": "サーバーが混雑しているか、プロンプトに「著作権用語」または「敏感な用語」が含まれています。もう一度お試しください。",
|
||||
"req_error_token": "トークンの有効性を確認してください",
|
||||
"required_field": "必須項目",
|
||||
"seed": "シード",
|
||||
|
||||
@ -1029,7 +1029,7 @@
|
||||
"turbo": "Быстро"
|
||||
},
|
||||
"req_error_no_balance": "Пожалуйста, проверьте действительность токена",
|
||||
"req_error_text": "Операция не удалась, повторите попытку. Пожалуйста, избегайте защищенных авторским правом терминов и конфиденциальных слов в запросах.",
|
||||
"req_error_text": "Сервер перегружен или в запросе обнаружены «авторские» либо «чувствительные» слова. Пожалуйста, повторите попытку.",
|
||||
"req_error_token": "Пожалуйста, проверьте действительность токена",
|
||||
"required_field": "Обязательное поле",
|
||||
"seed": "Ключ генерации",
|
||||
|
||||
@ -1029,7 +1029,7 @@
|
||||
"turbo": "快速"
|
||||
},
|
||||
"req_error_no_balance": "请检查令牌有效性",
|
||||
"req_error_text": "运行失败,请重试。提示词避免 \"版权词\" 和 \"敏感词\" 哦。",
|
||||
"req_error_text": "服务器繁忙或提示词出现 \"版权词\" 和 \"敏感词\" ,请重试。",
|
||||
"req_error_token": "请检查令牌有效性",
|
||||
"required_field": "必填项",
|
||||
"seed": "随机种子",
|
||||
|
||||
@ -1029,7 +1029,7 @@
|
||||
"turbo": "快速"
|
||||
},
|
||||
"req_error_no_balance": "請檢查令牌的有效性",
|
||||
"req_error_text": "运行失败,请重试。提示词避免 “版权词” 和” 敏感词” 哦。",
|
||||
"req_error_text": "伺服器繁忙或提示詞中出現「版權詞」或「敏感詞」,請重試。",
|
||||
"req_error_token": "請檢查令牌的有效性",
|
||||
"required_field": "必填欄位",
|
||||
"seed": "隨機種子",
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
import { PlusOutlined, RedoOutlined } from '@ant-design/icons'
|
||||
import DMXAPIToImg from '@renderer/assets/images/providers/DMXAPI-to-img.webp'
|
||||
import { Navbar, NavbarCenter, NavbarRight } from '@renderer/components/app/Navbar'
|
||||
import { VStack } from '@renderer/components/Layout'
|
||||
import { HStack } from '@renderer/components/Layout'
|
||||
import { HStack, VStack } from '@renderer/components/Layout'
|
||||
import Scrollbar from '@renderer/components/Scrollbar'
|
||||
import { isMac } from '@renderer/config/constant'
|
||||
import { getProviderLogo } from '@renderer/config/providers'
|
||||
@ -19,8 +18,7 @@ import { DmxapiPainting } from '@types'
|
||||
import { Avatar, Button, Input, Radio, Segmented, Select, Switch, Tooltip } from 'antd'
|
||||
import TextArea from 'antd/es/input/TextArea'
|
||||
import { Info } from 'lucide-react'
|
||||
import React, { FC } from 'react'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import React, { FC, useEffect, useRef, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import styled from 'styled-components'
|
||||
@ -32,14 +30,13 @@ import Artboard from './components/Artboard'
|
||||
import ImageUploader from './components/ImageUploader'
|
||||
import PaintingsList from './components/PaintingsList'
|
||||
import {
|
||||
ALL_MODELS,
|
||||
COURSE_URL,
|
||||
DEFAULT_PAINTING,
|
||||
IMAGE_EDIT_MODELS,
|
||||
IMAGE_MERGE_MODELS,
|
||||
IMAGE_SIZES,
|
||||
MODEL_GROUPS,
|
||||
MODEOPTIONS,
|
||||
STYLE_TYPE_OPTIONS,
|
||||
TEXT_TO_IMAGES_MODELS
|
||||
STYLE_TYPE_OPTIONS
|
||||
} from './config/DmxapiConfig'
|
||||
|
||||
const generateRandomSeed = () => Math.floor(Math.random() * 1000000).toString()
|
||||
@ -88,24 +85,15 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
|
||||
|
||||
const getModelOptions = (mode: generationModeType) => {
|
||||
if (mode === generationModeType.EDIT) {
|
||||
return IMAGE_EDIT_MODELS.map((model) => ({
|
||||
label: model.name,
|
||||
value: model.id
|
||||
}))
|
||||
return MODEL_GROUPS.IMAGE_EDIT
|
||||
}
|
||||
|
||||
if (mode === generationModeType.MERGE) {
|
||||
return IMAGE_MERGE_MODELS.map((model) => ({
|
||||
label: model.name,
|
||||
value: model.id
|
||||
}))
|
||||
return MODEL_GROUPS.IMAGE_MERGE
|
||||
}
|
||||
|
||||
// 默认情况或其它模式下的选项
|
||||
return TEXT_TO_IMAGES_MODELS.map((model) => ({
|
||||
label: model.name,
|
||||
value: model.id
|
||||
}))
|
||||
return MODEL_GROUPS.TEXT_TO_IMAGES
|
||||
}
|
||||
|
||||
const [modelOptions, setModelOptions] = useState(() => {
|
||||
@ -126,13 +114,22 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
|
||||
const getNewPainting = (params?: Partial<DmxapiPainting>) => {
|
||||
clearImages()
|
||||
const generationMode = params?.generationMode || painting?.generationMode || MODEOPTIONS[0].value
|
||||
const modelOptionsList = getModelOptions(generationMode as generationModeType)
|
||||
const modelGroups = getModelOptions(generationMode as generationModeType)
|
||||
// 获取第一个非空分组的第一个模型
|
||||
let firstModel = ''
|
||||
for (const provider of Object.keys(modelGroups)) {
|
||||
if (modelGroups[provider].length > 0) {
|
||||
firstModel = modelGroups[provider][0].id
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
...DEFAULT_PAINTING,
|
||||
id: uuid(),
|
||||
seed: generateRandomSeed(),
|
||||
generationMode,
|
||||
model: modelOptionsList[0]?.value,
|
||||
model: firstModel,
|
||||
...params
|
||||
}
|
||||
}
|
||||
@ -148,7 +145,7 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
|
||||
}
|
||||
|
||||
const onSelectModel = (modelId: string) => {
|
||||
const model = TEXT_TO_IMAGES_MODELS.find((m) => m.id === modelId)
|
||||
const model = ALL_MODELS.find((m) => m.id === modelId)
|
||||
if (model) {
|
||||
updatePaintingState({ model: modelId })
|
||||
}
|
||||
@ -222,9 +219,17 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
|
||||
|
||||
const onGenerationModeChange = (v: generationModeType) => {
|
||||
clearImages()
|
||||
const newModelOptions = getModelOptions(v)
|
||||
setModelOptions(newModelOptions)
|
||||
const firstModel = newModelOptions[0]?.value
|
||||
const newModelGroups = getModelOptions(v)
|
||||
setModelOptions(newModelGroups)
|
||||
|
||||
// 获取第一个非空分组的第一个模型
|
||||
let firstModel = ''
|
||||
for (const provider of Object.keys(newModelGroups)) {
|
||||
if (newModelGroups[provider].length > 0) {
|
||||
firstModel = newModelGroups[provider][0].id
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// 如果有urls,创建新的painting
|
||||
if (Array.isArray(painting.urls) && painting.urls.length > 0) {
|
||||
@ -376,13 +381,25 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
|
||||
|
||||
const data = await response.json()
|
||||
|
||||
if (
|
||||
painting.generationMode &&
|
||||
[generationModeType.EDIT, generationModeType.MERGE].includes(painting.generationMode)
|
||||
) {
|
||||
return data.data.map((item: { b64_json: string }) => 'data:image/png;base64,' + item.b64_json)
|
||||
}
|
||||
return data.data.map((item: { url: string }) => item.url)
|
||||
// if (
|
||||
// painting.generationMode &&
|
||||
// [generationModeType.EDIT, generationModeType.MERGE].includes(painting.generationMode)
|
||||
// ) {
|
||||
// return data.data.map((item: { b64_json: string }) => 'data:image/png;base64,' + item.b64_json)
|
||||
// }
|
||||
// return data.data.map((item: { url: string }) => item.url)
|
||||
|
||||
return data.data.map((item: { url: string; b64_json: string }) => {
|
||||
if (item.b64_json) {
|
||||
return 'data:image/png;base64,' + item.b64_json
|
||||
}
|
||||
|
||||
if (item.url) {
|
||||
return item.url
|
||||
}
|
||||
|
||||
return ''
|
||||
})
|
||||
}
|
||||
|
||||
// 下载图像函数
|
||||
@ -603,11 +620,11 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
|
||||
return (
|
||||
<LoadTextWrap>
|
||||
<div>
|
||||
正在用 OpenAI 官方 gpt-image-1 模型生产,
|
||||
正在用使用官方的模型生产,
|
||||
<br />
|
||||
预计等待2~5分钟效果最好,
|
||||
<br />
|
||||
本次消耗金额请到DMIAPI后台日志查看
|
||||
本次消耗金额请到DMXAPI后台日志查看
|
||||
</div>
|
||||
</LoadTextWrap>
|
||||
)
|
||||
@ -699,7 +716,20 @@ const DmxapiPage: FC<{ Options: string[] }> = ({ Options }) => {
|
||||
)}
|
||||
|
||||
<SettingTitle style={{ marginBottom: 5, marginTop: 15 }}>{t('common.model')}</SettingTitle>
|
||||
<Select value={painting.model} options={modelOptions} onChange={onSelectModel} />
|
||||
<Select value={painting.model} onChange={onSelectModel} style={{ width: '100%' }}>
|
||||
{Object.entries(modelOptions).map(([provider, models]) => {
|
||||
if (models.length === 0) return null
|
||||
return (
|
||||
<Select.OptGroup label={provider} key={provider}>
|
||||
{models.map((model) => (
|
||||
<Select.Option key={model.id} value={model.id}>
|
||||
{model.name}
|
||||
</Select.Option>
|
||||
))}
|
||||
</Select.OptGroup>
|
||||
)
|
||||
})}
|
||||
</Select>
|
||||
|
||||
{painting.generationMode === generationModeType.GENERATION && (
|
||||
<>
|
||||
|
||||
@ -42,27 +42,64 @@ export const STYLE_TYPE_OPTIONS = [
|
||||
export const TEXT_TO_IMAGES_MODELS = [
|
||||
{
|
||||
id: 'seedream-3.0',
|
||||
provider: 'DMXAPI',
|
||||
provider: 'doubao',
|
||||
name: ' 即梦 seedream-3.0'
|
||||
},
|
||||
{
|
||||
id: 'flux-kontext-pro',
|
||||
provider: 'Black Forest Labs',
|
||||
name: 'flux-kontext-pro'
|
||||
},
|
||||
{
|
||||
id: 'flux-kontext-max',
|
||||
provider: 'Black Forest Labs',
|
||||
name: 'flux-kontext-max'
|
||||
},
|
||||
{
|
||||
id: 'imagen4',
|
||||
provider: 'Google',
|
||||
name: 'imagen4'
|
||||
}
|
||||
]
|
||||
|
||||
export const IMAGE_EDIT_MODELS = [
|
||||
{
|
||||
id: 'gpt-image-1',
|
||||
provider: 'DMXAPI',
|
||||
name: 'OpenAI:gpt-image-1'
|
||||
provider: 'OpenAI',
|
||||
name: 'gpt-image-1'
|
||||
},
|
||||
{
|
||||
id: 'flux-kontext-pro',
|
||||
provider: 'Black Forest Labs',
|
||||
name: 'flux-kontext-pro'
|
||||
},
|
||||
{
|
||||
id: 'flux-kontext-max',
|
||||
provider: 'Black Forest Labs',
|
||||
name: 'flux-kontext-max'
|
||||
}
|
||||
]
|
||||
|
||||
export const IMAGE_MERGE_MODELS = [
|
||||
{
|
||||
id: 'gpt-image-1',
|
||||
provider: 'DMXAPI',
|
||||
name: 'OpenAI:gpt-image-1'
|
||||
provider: 'OpenAI',
|
||||
name: 'gpt-image-1'
|
||||
},
|
||||
{
|
||||
id: 'flux-kontext-pro',
|
||||
provider: 'Black Forest Labs',
|
||||
name: 'flux-kontext-pro'
|
||||
},
|
||||
{
|
||||
id: 'flux-kontext-max',
|
||||
provider: 'Black Forest Labs',
|
||||
name: 'flux-kontext-max'
|
||||
}
|
||||
]
|
||||
|
||||
export const ALL_MODELS = [...TEXT_TO_IMAGES_MODELS, ...IMAGE_EDIT_MODELS, ...IMAGE_MERGE_MODELS]
|
||||
|
||||
export const IMAGE_SIZES = [
|
||||
{
|
||||
label: '1:1',
|
||||
@ -118,3 +155,25 @@ export const MODEOPTIONS = [
|
||||
{ label: '改图', value: generationModeType.EDIT },
|
||||
{ label: '合并图', value: generationModeType.MERGE }
|
||||
]
|
||||
|
||||
// 按品牌分组的模型配置
|
||||
export const MODEL_GROUPS = {
|
||||
TEXT_TO_IMAGES: {
|
||||
Doubao: TEXT_TO_IMAGES_MODELS.filter((model) => model.provider === 'doubao'),
|
||||
OpenAI: TEXT_TO_IMAGES_MODELS.filter((model) => model.provider === 'OpenAI'),
|
||||
'Black Forest Labs': IMAGE_EDIT_MODELS.filter((model) => model.provider === 'Black Forest Labs'),
|
||||
Google: TEXT_TO_IMAGES_MODELS.filter((model) => model.provider === 'Google')
|
||||
},
|
||||
IMAGE_EDIT: {
|
||||
Doubao: IMAGE_EDIT_MODELS.filter((model) => model.provider === 'doubao'),
|
||||
OpenAI: IMAGE_EDIT_MODELS.filter((model) => model.provider === 'OpenAI'),
|
||||
'Black Forest Labs': IMAGE_EDIT_MODELS.filter((model) => model.provider === 'Black Forest Labs'),
|
||||
Google: IMAGE_EDIT_MODELS.filter((model) => model.provider === 'Google')
|
||||
},
|
||||
IMAGE_MERGE: {
|
||||
Doubao: IMAGE_MERGE_MODELS.filter((model) => model.provider === 'doubao'),
|
||||
OpenAI: IMAGE_MERGE_MODELS.filter((model) => model.provider === 'OpenAI'),
|
||||
'Black Forest Labs': IMAGE_MERGE_MODELS.filter((model) => model.provider === 'Black Forest Labs'),
|
||||
Google: IMAGE_MERGE_MODELS.filter((model) => model.provider === 'Google')
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user