mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-08 22:39:36 +08:00
feat(video): add video model validation and settings improvements
- Introduce new utility and config files for video model validation - Refactor ModelSetting component to use centralized video models config - Update VideoPage to handle video params with proper model validation
This commit is contained in:
parent
377b2b796f
commit
f61cadd5b5
6
src/renderer/src/config/models/video.ts
Normal file
6
src/renderer/src/config/models/video.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import { SystemProviderId } from '@renderer/types'
|
||||||
|
|
||||||
|
// Hard-encoded for now. We may implement a function to filter video generation model from provider.models.
|
||||||
|
export const videoModelsMap = {
|
||||||
|
openai: ['sora-2', 'sora-2-pro'] as const
|
||||||
|
} as const satisfies Partial<Record<SystemProviderId, string[]>>
|
||||||
@ -4,19 +4,47 @@ import { Divider } from '@heroui/react'
|
|||||||
import { Navbar, NavbarCenter } from '@renderer/components/app/Navbar'
|
import { Navbar, NavbarCenter } from '@renderer/components/app/Navbar'
|
||||||
import { useProvider } from '@renderer/hooks/useProvider'
|
import { useProvider } from '@renderer/hooks/useProvider'
|
||||||
import { SystemProviderIds } from '@renderer/types'
|
import { SystemProviderIds } from '@renderer/types'
|
||||||
import { useState } from 'react'
|
import { CreateVideoParams } from '@renderer/types/video'
|
||||||
|
import { isVideoModel } from '@renderer/utils/model/video'
|
||||||
|
import { DeepPartial } from 'ai'
|
||||||
|
import { merge } from 'lodash'
|
||||||
|
import { useCallback, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
import { ModelSetting } from './settings/ModelSetting'
|
import { ModelSetting } from './settings/ModelSetting'
|
||||||
|
import { OpenAIParamSettings } from './settings/OpenAIParamSettings'
|
||||||
import { ProviderSetting } from './settings/ProviderSetting'
|
import { ProviderSetting } from './settings/ProviderSetting'
|
||||||
|
import { SettingsGroup } from './settings/shared'
|
||||||
import { VideoList } from './VideoList'
|
import { VideoList } from './VideoList'
|
||||||
import { VideoPanel } from './VideoPanel'
|
import { VideoPanel } from './VideoPanel'
|
||||||
|
|
||||||
export const VideoPage = () => {
|
export const VideoPage = () => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const [providerId, setProviderId] = useState<string>(SystemProviderIds.openai)
|
const [providerId, setProviderId] = useState<string>(SystemProviderIds.openai)
|
||||||
const [modelId, setModelId] = useState('sora-2')
|
|
||||||
const { provider } = useProvider(providerId)
|
const { provider } = useProvider(providerId)
|
||||||
|
const [params, setParams] = useState<CreateVideoParams>({
|
||||||
|
type: 'openai',
|
||||||
|
provider,
|
||||||
|
params: {
|
||||||
|
model: 'sora-2',
|
||||||
|
prompt: ''
|
||||||
|
},
|
||||||
|
options: {}
|
||||||
|
})
|
||||||
|
|
||||||
|
const updateParams = useCallback((update: DeepPartial<Omit<CreateVideoParams, 'type'>>) => {
|
||||||
|
setParams((prev) => merge({}, prev, update))
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const updateModelId = useCallback(
|
||||||
|
(id: string) => {
|
||||||
|
if (isVideoModel(id)) {
|
||||||
|
updateParams({ params: { model: id } })
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[updateParams]
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-1 flex-col">
|
<div className="flex flex-1 flex-col">
|
||||||
<Navbar>
|
<Navbar>
|
||||||
@ -25,8 +53,15 @@ export const VideoPage = () => {
|
|||||||
<div id="content-container" className="flex flex-1">
|
<div id="content-container" className="flex flex-1">
|
||||||
{/* Settings */}
|
{/* Settings */}
|
||||||
<div className="flex w-70 flex-col p-2">
|
<div className="flex w-70 flex-col p-2">
|
||||||
<ProviderSetting providerId={providerId} setProviderId={setProviderId} />
|
<SettingsGroup>
|
||||||
<ModelSetting providerId={providerId} modelId={modelId} setModelId={setModelId} />
|
<ProviderSetting providerId={providerId} setProviderId={setProviderId} />
|
||||||
|
<ModelSetting
|
||||||
|
providerId={providerId}
|
||||||
|
modelId={params.params.model ?? 'sora-2'}
|
||||||
|
setModelId={updateModelId}
|
||||||
|
/>
|
||||||
|
</SettingsGroup>
|
||||||
|
{provider.type === 'openai-response' && <OpenAIParamSettings params={params} updateParams={updateParams} />}
|
||||||
</div>
|
</div>
|
||||||
<Divider orientation="vertical" />
|
<Divider orientation="vertical" />
|
||||||
<VideoPanel provider={provider} />
|
<VideoPanel provider={provider} />
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
import { Select, SelectItem } from '@heroui/react'
|
import { Select, SelectItem } from '@heroui/react'
|
||||||
import { Model, SystemProviderId } from '@renderer/types'
|
import { videoModelsMap } from '@renderer/config/models/video'
|
||||||
import { Dispatch, SetStateAction } from 'react'
|
import { Model } from '@renderer/types'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
import { SettingItem, SettingTitle } from './shared'
|
import { SettingItem } from './shared'
|
||||||
|
|
||||||
export interface ModelSettingProps {
|
export interface ModelSettingProps {
|
||||||
providerId: string
|
providerId: string
|
||||||
modelId: string
|
modelId: string
|
||||||
setModelId: Dispatch<SetStateAction<string>>
|
setModelId: (id: string) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ModelSelectItem extends Model {
|
interface ModelSelectItem extends Model {
|
||||||
@ -16,11 +16,6 @@ interface ModelSelectItem extends Model {
|
|||||||
label: string
|
label: string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hard-encoded for now. We may implement a function to filter video generation model from provider.models.
|
|
||||||
const videoModelsMap = {
|
|
||||||
openai: ['sora-2', 'sora-2-pro'] as const
|
|
||||||
} as const satisfies Partial<Record<SystemProviderId, string[]>>
|
|
||||||
|
|
||||||
export const ModelSetting = ({ providerId, modelId, setModelId }: ModelSettingProps) => {
|
export const ModelSetting = ({ providerId, modelId, setModelId }: ModelSettingProps) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
@ -28,8 +23,9 @@ export const ModelSetting = ({ providerId, modelId, setModelId }: ModelSettingPr
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<SettingItem>
|
<SettingItem>
|
||||||
<SettingTitle name={t('common.model')} />
|
|
||||||
<Select
|
<Select
|
||||||
|
label={t('common.model')}
|
||||||
|
labelPlacement="outside"
|
||||||
selectionMode="single"
|
selectionMode="single"
|
||||||
items={items}
|
items={items}
|
||||||
defaultSelectedKeys={[modelId]}
|
defaultSelectedKeys={[modelId]}
|
||||||
|
|||||||
7
src/renderer/src/utils/model/video.ts
Normal file
7
src/renderer/src/utils/model/video.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import { VideoModel } from '@cherrystudio/openai/resources'
|
||||||
|
import { videoModelsMap } from '@renderer/config/models/video'
|
||||||
|
|
||||||
|
// Only for openai, use hard-encoded values
|
||||||
|
export const isVideoModel = (modelId: string): modelId is VideoModel => {
|
||||||
|
return videoModelsMap.openai.some((v) => v === modelId)
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user