fix(providers): add Moonshot (Global) provider for api.moonshot.ai endpoint (#839)
Co-authored-by: octo-patch <octo-patch@github.com>
This commit is contained in:
committed by
GitHub
Unverified
parent
b2c478d554
commit
5482acd43d
@@ -144,6 +144,37 @@ export const PROVIDER_DEFINITIONS: ProviderDefinition[] = [
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'moonshot-global',
|
||||||
|
name: 'Moonshot (Global)',
|
||||||
|
icon: '🌙',
|
||||||
|
placeholder: 'sk-...',
|
||||||
|
model: 'Kimi',
|
||||||
|
requiresApiKey: true,
|
||||||
|
defaultBaseUrl: 'https://api.moonshot.ai/v1',
|
||||||
|
defaultModelId: 'kimi-k2.5',
|
||||||
|
category: 'official',
|
||||||
|
envVar: 'MOONSHOT_GLOBAL_API_KEY',
|
||||||
|
supportedAuthModes: ['api_key'],
|
||||||
|
defaultAuthMode: 'api_key',
|
||||||
|
supportsMultipleAccounts: true,
|
||||||
|
providerConfig: {
|
||||||
|
baseUrl: 'https://api.moonshot.ai/v1',
|
||||||
|
api: 'openai-completions',
|
||||||
|
apiKeyEnv: 'MOONSHOT_GLOBAL_API_KEY',
|
||||||
|
models: [
|
||||||
|
{
|
||||||
|
id: 'kimi-k2.5',
|
||||||
|
name: 'Kimi K2.5',
|
||||||
|
reasoning: false,
|
||||||
|
input: ['text'],
|
||||||
|
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
||||||
|
contextWindow: 256000,
|
||||||
|
maxTokens: 8192,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 'siliconflow',
|
id: 'siliconflow',
|
||||||
name: 'SiliconFlow (CN)',
|
name: 'SiliconFlow (CN)',
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import {
|
|||||||
} from './provider-registry';
|
} from './provider-registry';
|
||||||
import {
|
import {
|
||||||
OPENCLAW_PROVIDER_KEY_MOONSHOT,
|
OPENCLAW_PROVIDER_KEY_MOONSHOT,
|
||||||
|
OPENCLAW_PROVIDER_KEY_MOONSHOT_GLOBAL,
|
||||||
isOAuthProviderType,
|
isOAuthProviderType,
|
||||||
isOpenClawOAuthPluginProviderKey,
|
isOpenClawOAuthPluginProviderKey,
|
||||||
} from './provider-keys';
|
} from './provider-keys';
|
||||||
@@ -849,14 +850,16 @@ function removeLegacyMoonshotKimiSearchConfig(config: Record<string, unknown>):
|
|||||||
|
|
||||||
function upsertMoonshotWebSearchConfig(
|
function upsertMoonshotWebSearchConfig(
|
||||||
config: Record<string, unknown>,
|
config: Record<string, unknown>,
|
||||||
|
providerKey: string,
|
||||||
|
baseUrl: string,
|
||||||
legacyKimi?: Record<string, unknown>,
|
legacyKimi?: Record<string, unknown>,
|
||||||
): void {
|
): void {
|
||||||
const plugins = isPlainRecord(config.plugins)
|
const plugins = isPlainRecord(config.plugins)
|
||||||
? config.plugins
|
? config.plugins
|
||||||
: (Array.isArray(config.plugins) ? { load: [...config.plugins] } : {});
|
: (Array.isArray(config.plugins) ? { load: [...config.plugins] } : {});
|
||||||
const entries = isPlainRecord(plugins.entries) ? plugins.entries : {};
|
const entries = isPlainRecord(plugins.entries) ? plugins.entries : {};
|
||||||
const moonshot = isPlainRecord(entries[OPENCLAW_PROVIDER_KEY_MOONSHOT])
|
const moonshot = isPlainRecord(entries[providerKey])
|
||||||
? entries[OPENCLAW_PROVIDER_KEY_MOONSHOT] as Record<string, unknown>
|
? entries[providerKey] as Record<string, unknown>
|
||||||
: {};
|
: {};
|
||||||
const moonshotConfig = isPlainRecord(moonshot.config) ? moonshot.config as Record<string, unknown> : {};
|
const moonshotConfig = isPlainRecord(moonshot.config) ? moonshot.config as Record<string, unknown> : {};
|
||||||
const currentWebSearch = isPlainRecord(moonshotConfig.webSearch)
|
const currentWebSearch = isPlainRecord(moonshotConfig.webSearch)
|
||||||
@@ -865,25 +868,27 @@ function upsertMoonshotWebSearchConfig(
|
|||||||
|
|
||||||
const nextWebSearch = { ...(legacyKimi || {}), ...currentWebSearch };
|
const nextWebSearch = { ...(legacyKimi || {}), ...currentWebSearch };
|
||||||
delete nextWebSearch.apiKey;
|
delete nextWebSearch.apiKey;
|
||||||
nextWebSearch.baseUrl = 'https://api.moonshot.cn/v1';
|
nextWebSearch.baseUrl = baseUrl;
|
||||||
|
|
||||||
moonshotConfig.webSearch = nextWebSearch;
|
moonshotConfig.webSearch = nextWebSearch;
|
||||||
moonshot.config = moonshotConfig;
|
moonshot.config = moonshotConfig;
|
||||||
entries[OPENCLAW_PROVIDER_KEY_MOONSHOT] = moonshot;
|
entries[providerKey] = moonshot;
|
||||||
plugins.entries = entries;
|
plugins.entries = entries;
|
||||||
config.plugins = plugins;
|
config.plugins = plugins;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ensureMoonshotKimiWebSearchCnBaseUrl(config: Record<string, unknown>, provider: string): void {
|
function ensureMoonshotKimiWebSearchCnBaseUrl(config: Record<string, unknown>, provider: string): void {
|
||||||
if (provider !== OPENCLAW_PROVIDER_KEY_MOONSHOT) return;
|
if (provider === OPENCLAW_PROVIDER_KEY_MOONSHOT) {
|
||||||
|
|
||||||
const tools = isPlainRecord(config.tools) ? config.tools : null;
|
const tools = isPlainRecord(config.tools) ? config.tools : null;
|
||||||
const web = tools && isPlainRecord(tools.web) ? tools.web : null;
|
const web = tools && isPlainRecord(tools.web) ? tools.web : null;
|
||||||
const search = web && isPlainRecord(web.search) ? web.search : null;
|
const search = web && isPlainRecord(web.search) ? web.search : null;
|
||||||
const legacyKimi = search && isPlainRecord(search.kimi) ? search.kimi : undefined;
|
const legacyKimi = search && isPlainRecord(search.kimi) ? search.kimi : undefined;
|
||||||
|
|
||||||
upsertMoonshotWebSearchConfig(config, legacyKimi);
|
upsertMoonshotWebSearchConfig(config, OPENCLAW_PROVIDER_KEY_MOONSHOT, 'https://api.moonshot.cn/v1', legacyKimi);
|
||||||
removeLegacyMoonshotKimiSearchConfig(config);
|
removeLegacyMoonshotKimiSearchConfig(config);
|
||||||
|
} else if (provider === OPENCLAW_PROVIDER_KEY_MOONSHOT_GLOBAL) {
|
||||||
|
upsertMoonshotWebSearchConfig(config, OPENCLAW_PROVIDER_KEY_MOONSHOT_GLOBAL, 'https://api.moonshot.ai/v1');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1461,7 +1466,7 @@ export async function sanitizeOpenClawConfig(): Promise<void> {
|
|||||||
const hadLegacyKimi = Boolean(legacyKimi);
|
const hadLegacyKimi = Boolean(legacyKimi);
|
||||||
|
|
||||||
if (legacyKimi) {
|
if (legacyKimi) {
|
||||||
upsertMoonshotWebSearchConfig(config, legacyKimi);
|
upsertMoonshotWebSearchConfig(config, OPENCLAW_PROVIDER_KEY_MOONSHOT, 'https://api.moonshot.cn/v1', legacyKimi);
|
||||||
removeLegacyMoonshotKimiSearchConfig(config);
|
removeLegacyMoonshotKimiSearchConfig(config);
|
||||||
modified = true;
|
modified = true;
|
||||||
console.log('[sanitize] Migrated legacy "tools.web.search.kimi" to "plugins.entries.moonshot.config.webSearch"');
|
console.log('[sanitize] Migrated legacy "tools.web.search.kimi" to "plugins.entries.moonshot.config.webSearch"');
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ const MULTI_INSTANCE_PROVIDER_TYPES = new Set(['custom', 'ollama']);
|
|||||||
|
|
||||||
export const OPENCLAW_PROVIDER_KEY_MINIMAX = 'minimax-portal';
|
export const OPENCLAW_PROVIDER_KEY_MINIMAX = 'minimax-portal';
|
||||||
export const OPENCLAW_PROVIDER_KEY_MOONSHOT = 'moonshot';
|
export const OPENCLAW_PROVIDER_KEY_MOONSHOT = 'moonshot';
|
||||||
|
export const OPENCLAW_PROVIDER_KEY_MOONSHOT_GLOBAL = 'moonshot-global';
|
||||||
export const OAUTH_PROVIDER_TYPES = ['minimax-portal', 'minimax-portal-cn'] as const;
|
export const OAUTH_PROVIDER_TYPES = ['minimax-portal', 'minimax-portal-cn'] as const;
|
||||||
export const OPENCLAW_OAUTH_PLUGIN_PROVIDER_KEYS = [
|
export const OPENCLAW_OAUTH_PLUGIN_PROVIDER_KEYS = [
|
||||||
OPENCLAW_PROVIDER_KEY_MINIMAX,
|
OPENCLAW_PROVIDER_KEY_MINIMAX,
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ export const providerIcons: Record<string, string> = {
|
|||||||
openrouter,
|
openrouter,
|
||||||
ark,
|
ark,
|
||||||
moonshot,
|
moonshot,
|
||||||
|
'moonshot-global': moonshot,
|
||||||
siliconflow,
|
siliconflow,
|
||||||
'minimax-portal': minimaxPortal,
|
'minimax-portal': minimaxPortal,
|
||||||
'minimax-portal-cn': minimaxPortal,
|
'minimax-portal-cn': minimaxPortal,
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ export const PROVIDER_TYPES = [
|
|||||||
'openrouter',
|
'openrouter',
|
||||||
'ark',
|
'ark',
|
||||||
'moonshot',
|
'moonshot',
|
||||||
|
'moonshot-global',
|
||||||
'siliconflow',
|
'siliconflow',
|
||||||
'minimax-portal',
|
'minimax-portal',
|
||||||
'minimax-portal-cn',
|
'minimax-portal-cn',
|
||||||
@@ -29,6 +30,7 @@ export const BUILTIN_PROVIDER_TYPES = [
|
|||||||
'openrouter',
|
'openrouter',
|
||||||
'ark',
|
'ark',
|
||||||
'moonshot',
|
'moonshot',
|
||||||
|
'moonshot-global',
|
||||||
'siliconflow',
|
'siliconflow',
|
||||||
'minimax-portal',
|
'minimax-portal',
|
||||||
'minimax-portal-cn',
|
'minimax-portal-cn',
|
||||||
@@ -172,6 +174,7 @@ export const PROVIDER_TYPE_INFO: ProviderTypeInfo[] = [
|
|||||||
{ id: 'openrouter', name: 'OpenRouter', icon: '🌐', placeholder: 'sk-or-v1-...', model: 'Multi-Model', requiresApiKey: true, showModelId: true, modelIdPlaceholder: 'openai/gpt-5.4', defaultModelId: 'openai/gpt-5.4', docsUrl: 'https://openrouter.ai/models' },
|
{ id: 'openrouter', name: 'OpenRouter', icon: '🌐', placeholder: 'sk-or-v1-...', model: 'Multi-Model', requiresApiKey: true, showModelId: true, modelIdPlaceholder: 'openai/gpt-5.4', defaultModelId: 'openai/gpt-5.4', docsUrl: 'https://openrouter.ai/models' },
|
||||||
{ id: 'minimax-portal-cn', name: 'MiniMax (CN)', icon: '☁️', placeholder: 'sk-...', model: 'MiniMax', requiresApiKey: false, isOAuth: true, supportsApiKey: true, defaultModelId: 'MiniMax-M2.7', showModelId: true, showModelIdInDevModeOnly: true, modelIdPlaceholder: 'MiniMax-M2.7', apiKeyUrl: 'https://platform.minimaxi.com/' },
|
{ id: 'minimax-portal-cn', name: 'MiniMax (CN)', icon: '☁️', placeholder: 'sk-...', model: 'MiniMax', requiresApiKey: false, isOAuth: true, supportsApiKey: true, defaultModelId: 'MiniMax-M2.7', showModelId: true, showModelIdInDevModeOnly: true, modelIdPlaceholder: 'MiniMax-M2.7', apiKeyUrl: 'https://platform.minimaxi.com/' },
|
||||||
{ id: 'moonshot', name: 'Moonshot (CN)', icon: '🌙', placeholder: 'sk-...', model: 'Kimi', requiresApiKey: true, defaultBaseUrl: 'https://api.moonshot.cn/v1', defaultModelId: 'kimi-k2.5', docsUrl: 'https://platform.moonshot.cn/' },
|
{ id: 'moonshot', name: 'Moonshot (CN)', icon: '🌙', placeholder: 'sk-...', model: 'Kimi', requiresApiKey: true, defaultBaseUrl: 'https://api.moonshot.cn/v1', defaultModelId: 'kimi-k2.5', docsUrl: 'https://platform.moonshot.cn/' },
|
||||||
|
{ id: 'moonshot-global', name: 'Moonshot (Global)', icon: '🌙', placeholder: 'sk-...', model: 'Kimi', requiresApiKey: true, defaultBaseUrl: 'https://api.moonshot.ai/v1', defaultModelId: 'kimi-k2.5', docsUrl: 'https://platform.moonshot.ai/' },
|
||||||
{ id: 'siliconflow', name: 'SiliconFlow (CN)', icon: '🌊', placeholder: 'sk-...', model: 'Multi-Model', requiresApiKey: true, defaultBaseUrl: 'https://api.siliconflow.cn/v1', showModelId: true, showModelIdInDevModeOnly: true, modelIdPlaceholder: 'deepseek-ai/DeepSeek-V3', defaultModelId: 'deepseek-ai/DeepSeek-V3', docsUrl: 'https://docs.siliconflow.cn/cn/userguide/introduction' },
|
{ id: 'siliconflow', name: 'SiliconFlow (CN)', icon: '🌊', placeholder: 'sk-...', model: 'Multi-Model', requiresApiKey: true, defaultBaseUrl: 'https://api.siliconflow.cn/v1', showModelId: true, showModelIdInDevModeOnly: true, modelIdPlaceholder: 'deepseek-ai/DeepSeek-V3', defaultModelId: 'deepseek-ai/DeepSeek-V3', docsUrl: 'https://docs.siliconflow.cn/cn/userguide/introduction' },
|
||||||
{ id: 'minimax-portal', name: 'MiniMax (Global)', icon: '☁️', placeholder: 'sk-...', model: 'MiniMax', requiresApiKey: false, isOAuth: true, supportsApiKey: true, defaultModelId: 'MiniMax-M2.7', showModelId: true, showModelIdInDevModeOnly: true, modelIdPlaceholder: 'MiniMax-M2.7', apiKeyUrl: 'https://platform.minimax.io' },
|
{ id: 'minimax-portal', name: 'MiniMax (Global)', icon: '☁️', placeholder: 'sk-...', model: 'MiniMax', requiresApiKey: false, isOAuth: true, supportsApiKey: true, defaultModelId: 'MiniMax-M2.7', showModelId: true, showModelIdInDevModeOnly: true, modelIdPlaceholder: 'MiniMax-M2.7', apiKeyUrl: 'https://platform.minimax.io' },
|
||||||
{ id: 'modelstudio', name: 'Model Studio', icon: '☁️', placeholder: 'sk-...', model: 'Qwen', requiresApiKey: true, defaultBaseUrl: 'https://coding.dashscope.aliyuncs.com/v1', showBaseUrl: true, defaultModelId: 'qwen3.5-plus', showModelId: true, showModelIdInDevModeOnly: true, modelIdPlaceholder: 'qwen3.5-plus', apiKeyUrl: 'https://bailian.console.aliyun.com/', hidden: true },
|
{ id: 'modelstudio', name: 'Model Studio', icon: '☁️', placeholder: 'sk-...', model: 'Qwen', requiresApiKey: true, defaultBaseUrl: 'https://coding.dashscope.aliyuncs.com/v1', showBaseUrl: true, defaultModelId: 'qwen3.5-plus', showModelId: true, showModelIdInDevModeOnly: true, modelIdPlaceholder: 'qwen3.5-plus', apiKeyUrl: 'https://bailian.console.aliyun.com/', hidden: true },
|
||||||
|
|||||||
Reference in New Issue
Block a user