Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { ModelProvider, ModelProviderEnum, ProviderSettings, SessionType } from 'src/shared/types'
import { ModelSettingUtil } from './interface'
import HuaweiCloudMaaS from '../models/huaweicloud-maas'
import BaseConfig from './base-config'

export default class HuaweiCloudMAASSettingUtil extends BaseConfig implements ModelSettingUtil {
public provider: ModelProvider = ModelProviderEnum.HuaweiCloudMaaS

async getCurrentModelDisplayName(
model: string,
sessionType: SessionType,
providerSettings?: ProviderSettings
): Promise<string> {
return `HuaweiCloudMaaS API (${providerSettings?.models?.find((m) => m.modelId === model)?.nickname || model})`
}

public getLocalOptionGroups() {
// HuaweiCloudMaaS支持的所有模型

const deepseekModels = [
'deepseek-r1-250528',
'DeepSeek-V3',
'DeepSeek-R1'
]

const qwenModels = [
'qwen3-235b-a22b',
'qwen3-32b'
]

return [
{
group_name: 'DeepSeek 系列',
options: deepseekModels.map((value) => ({
label: value,
value: value,
})),
collapsable: true,
},
{
group_name: '千问 系列',
options: qwenModels.map((value) => ({
label: value,
value: value,
})),
collapsable: true,
},
]
}

protected async listProviderModels() {
return []
}

isCurrentModelSupportImageInput(model: string): boolean {
return HuaweiCloudMaaS.helpers.isModelSupportVision(model)
}

isCurrentModelSupportToolUse(model: string): boolean {
return HuaweiCloudMaaS.helpers.isModelSupportToolUse(model)
}
}
2 changes: 2 additions & 0 deletions src/renderer/packages/model-setting-utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import PerplexitySettingUtil from './perplexity-setting-util'
import SiliconFlowSettingUtil from './siliconflow-setting-util'
import VolcEngineSettingUtil from './volcengine-setting-util'
import XAISettingUtil from './xai-setting-util'
import HuaweiCloudMAASSettingUtil from './huaweicloud-maas-setting-util'

export function getModelSettingUtil(aiProvider: ModelProvider): ModelSettingUtil {
const hash: Record<ModelProvider, new () => ModelSettingUtil> = {
Expand All @@ -33,6 +34,7 @@ export function getModelSettingUtil(aiProvider: ModelProvider): ModelSettingUtil
[ModelProviderEnum.LMStudio]: LMStudioSettingUtil,
[ModelProviderEnum.Perplexity]: PerplexitySettingUtil,
[ModelProviderEnum.XAI]: XAISettingUtil,
[ModelProviderEnum.HuaweiCloudMaaS]: HuaweiCloudMAASSettingUtil,
[ModelProviderEnum.Custom]: CustomModelSettingUtil,
}
const Class = hash[aiProvider] || CustomModelSettingUtil
Expand Down
95 changes: 95 additions & 0 deletions src/renderer/packages/models/huaweicloud-maas.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { fetchWithProxy } from '@/utils/request'
import { createOpenAICompatible } from '@ai-sdk/openai-compatible'
import { extractReasoningMiddleware, wrapLanguageModel } from 'ai'
import AbstractAISDKModel from './abstract-ai-sdk'
import { ProviderModelInfo } from 'src/shared/types'
import { fetchRemoteModels } from './openai-compatible'

const helpers = {
isModelSupportVision: (model: string) => {
// HuaweiCloudMaaS支持视觉的模型
return false
},
isModelSupportToolUse: (model: string) => {
// HuaweiCloudMaaS支持工具使用的模型(除了纯图像生成和推理专用模型)
const nonToolModels = [
'qwen3-235b-a22b',
'qwen3-32b'
]
return !nonToolModels.some(nonToolModel => model.includes(nonToolModel))
},
}

interface Options {
apiKey: string
apiHost: string
model: ProviderModelInfo
temperature?: number
topP?: number
useProxy?: boolean
}

export default class HuaweiCloudMaaS extends AbstractAISDKModel {
public name = 'HuaweiCloudMaaS'
public static helpers = helpers
public options: Options

constructor(options: Options) {
super(options)
this.options = {
...options,
apiHost: options.apiHost || 'https://ai.huaweicloud.com/v1',
}
}

public isSupportToolUse() {
return helpers.isModelSupportToolUse(this.options.model.modelId)
}

private getProvider() {
return createOpenAICompatible({
name: 'HuaweiCloudMaaS',
apiKey: this.options.apiKey,
baseURL: this.options.apiHost,
fetch: this.options.useProxy ? fetchWithProxy : undefined,
})
}

protected getChatModel() {
const provider = this.getProvider()
return wrapLanguageModel({
model: provider.languageModel(this.options.model.modelId),
middleware: extractReasoningMiddleware({ tagName: 'think' }),
})
}

protected getImageModel() {
const provider = this.getProvider()
return provider.imageModel('dall-e-3')
}

protected getCallSettings() {
return {
temperature: this.options.temperature,
topP: this.options.topP,
}
}

public async listModels(): Promise<string[]> {
return fetchRemoteModels({
apiHost: this.options.apiHost,
apiKey: this.options.apiKey,
useProxy: this.options.useProxy,
}).catch((err) => {
console.error('HuaweiCloudMaaS models fetch error:', err)
// 返回HuaweiCloudMaaS支持的常见模型作为备选
return [
'deepseek-r1-250528',
'DeepSeek-V3',
'DeepSeek-R1',
'qwen3-235b-a22b',
'qwen3-32b'
]
})
}
}
10 changes: 10 additions & 0 deletions src/renderer/packages/models/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import SiliconFlow from './siliconflow'
import type { ModelInterface } from './types'
import VolcEngine from './volcengine'
import XAI from './xai'
import HuaweiCloudMaaS from './huaweicloud-maas'

export function getModel(setting: Settings, config: Config): ModelInterface {
const provider = setting.provider
Expand Down Expand Up @@ -126,6 +127,15 @@ export function getModel(setting: Settings, config: Config): ModelInterface {
topP: setting.topP,
})

case ModelProviderEnum.HuaweiCloudMaaS:
return new HuaweiCloudMaaS({
apiKey: providerSetting.apiKey || '',
apiHost: formattedApiHost,
model,
temperature: setting.temperature,
topP: setting.topP,
})
Comment on lines +130 to +137
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Model instantiation is correct but missing UI mappings.

The model instantiation follows the established pattern and uses appropriate constructor parameters. However, HuaweiCloudMaaS is missing from both aiProviderNameHash (lines 195-211) and AIModelProviderMenuOptionList (lines 213-285), which are likely used for UI display purposes.

Add the missing entries to enable proper UI display:

export const aiProviderNameHash: Record<ModelProvider, string> = {
  [ModelProviderEnum.OpenAI]: 'OpenAI API',
  [ModelProviderEnum.Azure]: 'Azure OpenAI API',
  [ModelProviderEnum.ChatGLM6B]: 'ChatGLM API',
  [ModelProviderEnum.ChatboxAI]: 'Chatbox AI',
  [ModelProviderEnum.Claude]: 'Claude API',
  [ModelProviderEnum.Gemini]: 'Google Gemini API',
  [ModelProviderEnum.Ollama]: 'Ollama API',
  [ModelProviderEnum.Groq]: 'Groq API',
  [ModelProviderEnum.DeepSeek]: 'DeepSeek API',
  [ModelProviderEnum.SiliconFlow]: 'SiliconFlow API',
  [ModelProviderEnum.VolcEngine]: 'VolcEngine API',
  [ModelProviderEnum.LMStudio]: 'LM Studio API',
  [ModelProviderEnum.Perplexity]: 'Perplexity API',
  [ModelProviderEnum.XAI]: 'xAI API',
+ [ModelProviderEnum.HuaweiCloudMaaS]: 'HuaweiCloudMaaS API',
  [ModelProviderEnum.Custom]: 'Custom Provider',
}

And add to the menu options list:

export const AIModelProviderMenuOptionList = [
  // ... existing entries ...
  {
    value: ModelProviderEnum.ChatGLM6B,
    label: aiProviderNameHash[ModelProviderEnum.ChatGLM6B],
    disabled: false,
  },
+ {
+   value: ModelProviderEnum.HuaweiCloudMaaS,
+   label: aiProviderNameHash[ModelProviderEnum.HuaweiCloudMaaS],
+   disabled: false,
+ },
]
🤖 Prompt for AI Agents
In src/renderer/packages/models/index.ts around lines 130 to 137, the
HuaweiCloudMaaS model is instantiated correctly but is missing from the
aiProviderNameHash mapping (lines 195-211) and the AIModelProviderMenuOptionList
array (lines 213-285). To fix this, add an entry for HuaweiCloudMaaS in
aiProviderNameHash with the appropriate display name and icon, and also add a
corresponding menu option object for HuaweiCloudMaaS in
AIModelProviderMenuOptionList to ensure it appears properly in the UI.


case ModelProviderEnum.SiliconFlow:
return new SiliconFlow({
siliconCloudKey: providerSetting.apiKey || '',
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 35 additions & 0 deletions src/shared/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -592,4 +592,39 @@ export const SystemProviders: ProviderBaseInfo[] = [
],
},
},
{
id: ModelProviderEnum.HuaweiCloudMaaS,
name: 'HuaweiCloudMaaS',
type: ModelProviderType.OpenAI,
defaultSettings: {
apiHost: 'https://api.modelarts-maas.com/v1/',
models: [
{
modelId: 'deepseek-r1-250528',
capabilities: ['reasoning', 'tool_use'],
contextWindow: 64_000,
},
{
modelId: 'DeepSeek-V3',
capabilities: ['tool_use'],
contextWindow: 64_000,
},
{
modelId: 'DeepSeek-R1',
capabilities: ['reasoning', 'tool_use'],
contextWindow: 64_000,
},
{
modelId: 'qwen3-235b-a22b',
capabilities: ['reasoning'],
contextWindow: 32_000,
},
{
modelId: 'qwen3-32b',
capabilities: ['reasoning'],
contextWindow: 32_000,
}
],
},
},
]
1 change: 1 addition & 0 deletions src/shared/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,7 @@ export enum ModelProviderEnum {
Perplexity = 'perplexity',
XAI = 'xAI',
Custom = 'custom',
HuaweiCloudMaaS = 'huaweicloud-maas',
}
export type ModelProvider = ModelProviderEnum | string

Expand Down