mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-04 11:49:02 +08:00
feat: add project name support for Volcengine integration
This commit is contained in:
parent
c3c577dff4
commit
531101742e
@ -34,6 +34,7 @@ const ListFoundationModelsRequestSchema = z.object({
|
||||
})
|
||||
|
||||
const ListEndpointsRequestSchema = z.object({
|
||||
ProjectName: z.optional(z.string()),
|
||||
PageNumber: z.optional(z.number()),
|
||||
PageSize: z.optional(z.number())
|
||||
})
|
||||
@ -544,8 +545,9 @@ class VolcengineService {
|
||||
/**
|
||||
* List user-created endpoints from Volcengine ARK
|
||||
*/
|
||||
private async listEndpoints(): Promise<ListEndpointsResponse> {
|
||||
private async listEndpoints(projectName?: string): Promise<ListEndpointsResponse> {
|
||||
const requestBody: ListEndpointsRequest = {
|
||||
ProjectName: projectName || 'default',
|
||||
PageNumber: 1,
|
||||
PageSize: CONFIG.DEFAULT_PAGE_SIZE
|
||||
}
|
||||
@ -569,11 +571,11 @@ class VolcengineService {
|
||||
* List all available models from Volcengine ARK
|
||||
* Combines foundation models and user-created endpoints
|
||||
*/
|
||||
public listModels = async (): Promise<ListModelsResult> => {
|
||||
public listModels = async (_?: Electron.IpcMainInvokeEvent, projectName?: string): Promise<ListModelsResult> => {
|
||||
try {
|
||||
const [foundationModelsResult, endpointsResult] = await Promise.allSettled([
|
||||
this.listFoundationModels(),
|
||||
this.listEndpoints()
|
||||
this.listEndpoints(projectName)
|
||||
])
|
||||
|
||||
const models: ModelInfo[] = []
|
||||
|
||||
@ -578,10 +578,10 @@ const api = {
|
||||
ipcRenderer.invoke(IpcChannel.Volcengine_SaveCredentials, accessKeyId, secretAccessKey),
|
||||
hasCredentials: (): Promise<boolean> => ipcRenderer.invoke(IpcChannel.Volcengine_HasCredentials),
|
||||
clearCredentials: (): Promise<void> => ipcRenderer.invoke(IpcChannel.Volcengine_ClearCredentials),
|
||||
listModels: (): Promise<{
|
||||
listModels: (projectName?: string): Promise<{
|
||||
models: Array<{ id: string; name: string; description?: string; created?: number }>
|
||||
total?: number
|
||||
}> => ipcRenderer.invoke(IpcChannel.Volcengine_ListModels),
|
||||
}> => ipcRenderer.invoke(IpcChannel.Volcengine_ListModels, projectName),
|
||||
getAuthHeaders: (params: {
|
||||
method: 'GET' | 'POST'
|
||||
host: string
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import type OpenAI from '@cherrystudio/openai'
|
||||
import { loggerService } from '@logger'
|
||||
import { getVolcengineProjectName } from '@renderer/hooks/useVolcengine'
|
||||
import type { Provider } from '@renderer/types'
|
||||
|
||||
import { OpenAIAPIClient } from '../openai/OpenAIApiClient'
|
||||
@ -33,7 +34,8 @@ export class VolcengineAPIClient extends OpenAIAPIClient {
|
||||
|
||||
logger.info('Fetching models from Volcengine API using signed request')
|
||||
|
||||
const response = await window.api.volcengine.listModels()
|
||||
const projectName = getVolcengineProjectName()
|
||||
const response = await window.api.volcengine.listModels(projectName)
|
||||
|
||||
if (!response || !response.models) {
|
||||
logger.warn('Empty response from Volcengine listModels')
|
||||
|
||||
@ -1,5 +1,10 @@
|
||||
import store, { useAppSelector } from '@renderer/store'
|
||||
import { setVolcengineAccessKeyId, setVolcengineRegion, setVolcengineSecretAccessKey } from '@renderer/store/llm'
|
||||
import {
|
||||
setVolcengineAccessKeyId,
|
||||
setVolcengineProjectName,
|
||||
setVolcengineRegion,
|
||||
setVolcengineSecretAccessKey
|
||||
} from '@renderer/store/llm'
|
||||
import { useDispatch } from 'react-redux'
|
||||
|
||||
export function useVolcengineSettings() {
|
||||
@ -10,7 +15,8 @@ export function useVolcengineSettings() {
|
||||
...settings,
|
||||
setAccessKeyId: (accessKeyId: string) => dispatch(setVolcengineAccessKeyId(accessKeyId)),
|
||||
setSecretAccessKey: (secretAccessKey: string) => dispatch(setVolcengineSecretAccessKey(secretAccessKey)),
|
||||
setRegion: (region: string) => dispatch(setVolcengineRegion(region))
|
||||
setRegion: (region: string) => dispatch(setVolcengineRegion(region)),
|
||||
setProjectName: (projectName: string) => dispatch(setVolcengineProjectName(projectName))
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,3 +35,7 @@ export function getVolcengineSecretAccessKey() {
|
||||
export function getVolcengineRegion() {
|
||||
return store.getState().llm.settings.volcengine.region
|
||||
}
|
||||
|
||||
export function getVolcengineProjectName() {
|
||||
return store.getState().llm.settings.volcengine.projectName
|
||||
}
|
||||
|
||||
@ -4519,6 +4519,8 @@
|
||||
"credentials_required": "Please fill in Access Key ID and Secret Access Key",
|
||||
"credentials_saved": "Credentials saved",
|
||||
"description": "Volcengine is ByteDance's cloud service platform, providing Doubao and other large language model services. Please use IAM user's Access Key for authentication, do not use the root user credentials.",
|
||||
"project_name": "Project Name",
|
||||
"project_name_help": "Project name for endpoint filtering, default is 'default'",
|
||||
"region": "Region",
|
||||
"region_help": "Service region, e.g., cn-beijing",
|
||||
"save_credentials": "Save Credentials",
|
||||
|
||||
@ -4519,6 +4519,8 @@
|
||||
"credentials_required": "请填写 Access Key ID 和 Secret Access Key",
|
||||
"credentials_saved": "凭证已保存",
|
||||
"description": "火山引擎是字节跳动旗下的云服务平台,提供豆包等大语言模型服务。请使用 IAM 子用户的 Access Key 进行身份验证,不要使用主账号的根用户密钥。",
|
||||
"project_name": "项目名称",
|
||||
"project_name_help": "用于筛选推理接入点的项目名称,默认为 'default'",
|
||||
"region": "地域",
|
||||
"region_help": "服务地域,例如 cn-beijing",
|
||||
"save_credentials": "保存凭证",
|
||||
|
||||
@ -4519,6 +4519,8 @@
|
||||
"credentials_required": "請填寫 Access Key ID 和 Secret Access Key",
|
||||
"credentials_saved": "憑證已儲存",
|
||||
"description": "火山引擎是字節跳動旗下的雲端服務平台,提供豆包等大型語言模型服務。請使用 IAM 子用戶的 Access Key 進行身份驗證,不要使用主帳號的根用戶密鑰。",
|
||||
"project_name": "專案名稱",
|
||||
"project_name_help": "用於篩選推論接入點的專案名稱,預設為 'default'",
|
||||
"region": "地區",
|
||||
"region_help": "服務地區,例如 cn-beijing",
|
||||
"save_credentials": "儲存憑證",
|
||||
|
||||
@ -4519,6 +4519,8 @@
|
||||
"credentials_required": "[to be translated]:Please fill in Access Key ID and Secret Access Key",
|
||||
"credentials_saved": "[to be translated]:Credentials saved",
|
||||
"description": "[to be translated]:Volcengine is ByteDance's cloud service platform, providing Doubao and other large language model services. Use Access Key for authentication to fetch model list.",
|
||||
"project_name": "[to be translated]:Project Name",
|
||||
"project_name_help": "[to be translated]:Project name for endpoint filtering, default is 'default'",
|
||||
"region": "[to be translated]:Region",
|
||||
"region_help": "[to be translated]:Service region, e.g., cn-beijing",
|
||||
"save_credentials": "[to be translated]:Save Credentials",
|
||||
|
||||
@ -4519,6 +4519,8 @@
|
||||
"credentials_required": "[to be translated]:Please fill in Access Key ID and Secret Access Key",
|
||||
"credentials_saved": "[to be translated]:Credentials saved",
|
||||
"description": "[to be translated]:Volcengine is ByteDance's cloud service platform, providing Doubao and other large language model services. Use Access Key for authentication to fetch model list.",
|
||||
"project_name": "[to be translated]:Project Name",
|
||||
"project_name_help": "[to be translated]:Project name for endpoint filtering, default is 'default'",
|
||||
"region": "[to be translated]:Region",
|
||||
"region_help": "[to be translated]:Service region, e.g., cn-beijing",
|
||||
"save_credentials": "[to be translated]:Save Credentials",
|
||||
|
||||
@ -4519,6 +4519,8 @@
|
||||
"credentials_required": "[to be translated]:Please fill in Access Key ID and Secret Access Key",
|
||||
"credentials_saved": "[to be translated]:Credentials saved",
|
||||
"description": "[to be translated]:Volcengine is ByteDance's cloud service platform, providing Doubao and other large language model services. Use Access Key for authentication to fetch model list.",
|
||||
"project_name": "[to be translated]:Project Name",
|
||||
"project_name_help": "[to be translated]:Project name for endpoint filtering, default is 'default'",
|
||||
"region": "[to be translated]:Region",
|
||||
"region_help": "[to be translated]:Service region, e.g., cn-beijing",
|
||||
"save_credentials": "[to be translated]:Save Credentials",
|
||||
|
||||
@ -4519,6 +4519,8 @@
|
||||
"credentials_required": "[to be translated]:Please fill in Access Key ID and Secret Access Key",
|
||||
"credentials_saved": "[to be translated]:Credentials saved",
|
||||
"description": "[to be translated]:Volcengine is ByteDance's cloud service platform, providing Doubao and other large language model services. Use Access Key for authentication to fetch model list.",
|
||||
"project_name": "[to be translated]:Project Name",
|
||||
"project_name_help": "[to be translated]:Project name for endpoint filtering, default is 'default'",
|
||||
"region": "[to be translated]:Region",
|
||||
"region_help": "[to be translated]:Service region, e.g., cn-beijing",
|
||||
"save_credentials": "[to be translated]:Save Credentials",
|
||||
|
||||
@ -4519,6 +4519,8 @@
|
||||
"credentials_required": "[to be translated]:Please fill in Access Key ID and Secret Access Key",
|
||||
"credentials_saved": "[to be translated]:Credentials saved",
|
||||
"description": "[to be translated]:Volcengine is ByteDance's cloud service platform, providing Doubao and other large language model services. Use Access Key for authentication to fetch model list.",
|
||||
"project_name": "[to be translated]:Project Name",
|
||||
"project_name_help": "[to be translated]:Project name for endpoint filtering, default is 'default'",
|
||||
"region": "[to be translated]:Region",
|
||||
"region_help": "[to be translated]:Service region, e.g., cn-beijing",
|
||||
"save_credentials": "[to be translated]:Save Credentials",
|
||||
|
||||
@ -4519,6 +4519,8 @@
|
||||
"credentials_required": "[to be translated]:Please fill in Access Key ID and Secret Access Key",
|
||||
"credentials_saved": "[to be translated]:Credentials saved",
|
||||
"description": "[to be translated]:Volcengine is ByteDance's cloud service platform, providing Doubao and other large language model services. Use Access Key for authentication to fetch model list.",
|
||||
"project_name": "[to be translated]:Project Name",
|
||||
"project_name_help": "[to be translated]:Project name for endpoint filtering, default is 'default'",
|
||||
"region": "[to be translated]:Region",
|
||||
"region_help": "[to be translated]:Service region, e.g., cn-beijing",
|
||||
"save_credentials": "[to be translated]:Save Credentials",
|
||||
|
||||
@ -4519,6 +4519,8 @@
|
||||
"credentials_required": "[to be translated]:Please fill in Access Key ID and Secret Access Key",
|
||||
"credentials_saved": "[to be translated]:Credentials saved",
|
||||
"description": "[to be translated]:Volcengine is ByteDance's cloud service platform, providing Doubao and other large language model services. Use Access Key for authentication to fetch model list.",
|
||||
"project_name": "[to be translated]:Project Name",
|
||||
"project_name_help": "[to be translated]:Project name for endpoint filtering, default is 'default'",
|
||||
"region": "[to be translated]:Region",
|
||||
"region_help": "[to be translated]:Service region, e.g., cn-beijing",
|
||||
"save_credentials": "[to be translated]:Save Credentials",
|
||||
|
||||
@ -10,7 +10,7 @@ import { SettingHelpLink, SettingHelpText, SettingHelpTextRow, SettingSubtitle }
|
||||
|
||||
const VolcengineSettings: FC = () => {
|
||||
const { t } = useTranslation()
|
||||
const { accessKeyId, secretAccessKey, region, setAccessKeyId, setSecretAccessKey, setRegion } =
|
||||
const { accessKeyId, secretAccessKey, region, projectName, setAccessKeyId, setSecretAccessKey, setRegion, setProjectName } =
|
||||
useVolcengineSettings()
|
||||
|
||||
const providerConfig = PROVIDER_URLS['doubao']
|
||||
@ -19,6 +19,7 @@ const VolcengineSettings: FC = () => {
|
||||
const [localAccessKeyId, setLocalAccessKeyId] = useState(accessKeyId)
|
||||
const [localSecretAccessKey, setLocalSecretAccessKey] = useState(secretAccessKey)
|
||||
const [localRegion, setLocalRegion] = useState(region)
|
||||
const [localProjectName, setLocalProjectName] = useState(projectName)
|
||||
const [saving, setSaving] = useState(false)
|
||||
const [hasCredentials, setHasCredentials] = useState(false)
|
||||
|
||||
@ -32,7 +33,8 @@ const VolcengineSettings: FC = () => {
|
||||
setLocalAccessKeyId(accessKeyId)
|
||||
setLocalSecretAccessKey(secretAccessKey)
|
||||
setLocalRegion(region)
|
||||
}, [accessKeyId, secretAccessKey, region])
|
||||
setLocalProjectName(projectName)
|
||||
}, [accessKeyId, secretAccessKey, region, projectName])
|
||||
|
||||
const handleSaveCredentials = useCallback(async () => {
|
||||
if (!localAccessKeyId || !localSecretAccessKey) {
|
||||
@ -46,6 +48,7 @@ const VolcengineSettings: FC = () => {
|
||||
setAccessKeyId(localAccessKeyId)
|
||||
setSecretAccessKey(localSecretAccessKey)
|
||||
setRegion(localRegion)
|
||||
setProjectName(localProjectName)
|
||||
|
||||
// Save to secure storage via IPC
|
||||
await window.api.volcengine.saveCredentials(localAccessKeyId, localSecretAccessKey)
|
||||
@ -56,7 +59,7 @@ const VolcengineSettings: FC = () => {
|
||||
} finally {
|
||||
setSaving(false)
|
||||
}
|
||||
}, [localAccessKeyId, localSecretAccessKey, localRegion, setAccessKeyId, setSecretAccessKey, setRegion, t])
|
||||
}, [localAccessKeyId, localSecretAccessKey, localRegion, localProjectName, setAccessKeyId, setSecretAccessKey, setRegion, setProjectName, t])
|
||||
|
||||
const handleClearCredentials = useCallback(async () => {
|
||||
try {
|
||||
@ -122,6 +125,18 @@ const VolcengineSettings: FC = () => {
|
||||
<SettingHelpText>{t('settings.provider.volcengine.region_help')}</SettingHelpText>
|
||||
</SettingHelpTextRow>
|
||||
|
||||
<SettingSubtitle style={{ marginTop: 15 }}>{t('settings.provider.volcengine.project_name')}</SettingSubtitle>
|
||||
<Input
|
||||
value={localProjectName}
|
||||
placeholder="default"
|
||||
onChange={(e) => setLocalProjectName(e.target.value)}
|
||||
onBlur={() => setProjectName(localProjectName)}
|
||||
style={{ marginTop: 5 }}
|
||||
/>
|
||||
<SettingHelpTextRow>
|
||||
<SettingHelpText>{t('settings.provider.volcengine.project_name_help')}</SettingHelpText>
|
||||
</SettingHelpTextRow>
|
||||
|
||||
<Space style={{ marginTop: 15 }}>
|
||||
<Button type="primary" onClick={handleSaveCredentials} loading={saving}>
|
||||
{t('settings.provider.volcengine.save_credentials')}
|
||||
|
||||
@ -246,7 +246,8 @@ vi.mock('@renderer/store/llm.ts', () => {
|
||||
volcengine: {
|
||||
accessKeyId: '',
|
||||
secretAccessKey: '',
|
||||
region: 'cn-beijing'
|
||||
region: 'cn-beijing',
|
||||
projectName: 'default'
|
||||
}
|
||||
}
|
||||
} satisfies LlmState
|
||||
|
||||
@ -35,6 +35,7 @@ type LlmSettings = {
|
||||
accessKeyId: string
|
||||
secretAccessKey: string
|
||||
region: string
|
||||
projectName: string
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,7 +85,8 @@ export const initialState: LlmState = {
|
||||
volcengine: {
|
||||
accessKeyId: '',
|
||||
secretAccessKey: '',
|
||||
region: 'cn-beijing'
|
||||
region: 'cn-beijing',
|
||||
projectName: 'default'
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -235,6 +237,9 @@ const llmSlice = createSlice({
|
||||
setVolcengineRegion: (state, action: PayloadAction<string>) => {
|
||||
state.settings.volcengine.region = action.payload
|
||||
},
|
||||
setVolcengineProjectName: (state, action: PayloadAction<string>) => {
|
||||
state.settings.volcengine.projectName = action.payload
|
||||
},
|
||||
updateModel: (
|
||||
state,
|
||||
action: PayloadAction<{
|
||||
@ -279,6 +284,7 @@ export const {
|
||||
setVolcengineAccessKeyId,
|
||||
setVolcengineSecretAccessKey,
|
||||
setVolcengineRegion,
|
||||
setVolcengineProjectName,
|
||||
updateModel
|
||||
} = llmSlice.actions
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user