mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-28 21:42:27 +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 { useProvider } from '@renderer/hooks/useProvider'
|
||||
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 { ModelSetting } from './settings/ModelSetting'
|
||||
import { OpenAIParamSettings } from './settings/OpenAIParamSettings'
|
||||
import { ProviderSetting } from './settings/ProviderSetting'
|
||||
import { SettingsGroup } from './settings/shared'
|
||||
import { VideoList } from './VideoList'
|
||||
import { VideoPanel } from './VideoPanel'
|
||||
|
||||
export const VideoPage = () => {
|
||||
const { t } = useTranslation()
|
||||
const [providerId, setProviderId] = useState<string>(SystemProviderIds.openai)
|
||||
const [modelId, setModelId] = useState('sora-2')
|
||||
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 (
|
||||
<div className="flex flex-1 flex-col">
|
||||
<Navbar>
|
||||
@ -25,8 +53,15 @@ export const VideoPage = () => {
|
||||
<div id="content-container" className="flex flex-1">
|
||||
{/* Settings */}
|
||||
<div className="flex w-70 flex-col p-2">
|
||||
<ProviderSetting providerId={providerId} setProviderId={setProviderId} />
|
||||
<ModelSetting providerId={providerId} modelId={modelId} setModelId={setModelId} />
|
||||
<SettingsGroup>
|
||||
<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>
|
||||
<Divider orientation="vertical" />
|
||||
<VideoPanel provider={provider} />
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
import { Select, SelectItem } from '@heroui/react'
|
||||
import { Model, SystemProviderId } from '@renderer/types'
|
||||
import { Dispatch, SetStateAction } from 'react'
|
||||
import { videoModelsMap } from '@renderer/config/models/video'
|
||||
import { Model } from '@renderer/types'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import { SettingItem, SettingTitle } from './shared'
|
||||
import { SettingItem } from './shared'
|
||||
|
||||
export interface ModelSettingProps {
|
||||
providerId: string
|
||||
modelId: string
|
||||
setModelId: Dispatch<SetStateAction<string>>
|
||||
setModelId: (id: string) => void
|
||||
}
|
||||
|
||||
interface ModelSelectItem extends Model {
|
||||
@ -16,11 +16,6 @@ interface ModelSelectItem extends Model {
|
||||
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) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
@ -28,8 +23,9 @@ export const ModelSetting = ({ providerId, modelId, setModelId }: ModelSettingPr
|
||||
|
||||
return (
|
||||
<SettingItem>
|
||||
<SettingTitle name={t('common.model')} />
|
||||
<Select
|
||||
label={t('common.model')}
|
||||
labelPlacement="outside"
|
||||
selectionMode="single"
|
||||
items={items}
|
||||
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