1 line
22 KiB
JSON
1 line
22 KiB
JSON
{"repo": "chinmayshringi/mischiefclaw", "files": {"openclaw/extensions/minimax/src/minimax-web-search-provider.ts": {"425bd114a1b8efa3b2330bc3e0fa1fe346362b13": {"t": 1785674020.7505648, "n": 9828, "h": "dd306556f4b9fa7a", "c": "import { Type } from \"@sinclair/typebox\";\nimport {\n DEFAULT_SEARCH_COUNT,\n MAX_SEARCH_COUNT,\n buildSearchCacheKey,\n formatCliCommand,\n mergeScopedSearchConfig,\n readCachedSearchPayload,\n readConfiguredSecretString,\n readNumberParam,\n readProviderEnvValue,\n readStringParam,\n resolveProviderWebSearchPluginConfig,\n resolveSearchCacheTtlMs,\n resolveSearchCount,\n resolveSearchTimeoutSeconds,\n resolveSiteName,\n setProviderWebSearchPluginConfigValue,\n setTopLevelCredentialValue,\n withTrustedWebSearchEndpoint,\n wrapWebContent,\n writeCachedSearchPayload,\n type SearchConfigRecord,\n type WebSearchProviderPlugin,\n type WebSearchProviderToolDefinition,\n} from \"openclaw/plugin-sdk/provider-web-search\";\n\nconst MINIMAX_SEARCH_ENDPOINT_GLOBAL = \"https://api.minimax.io/v1/coding_plan/search\";\nconst MINIMAX_SEARCH_ENDPOINT_CN = \"https://api.minimaxi.com/v1/coding_plan/search\";\nconst MINIMAX_CODING_PLAN_ENV_VARS = [\"MINIMAX_CODE_PLAN_KEY\", \"MINIMAX_CODING_API_KEY\"] as const;\n\ntype MiniMaxSearchResult = {\n title?: string;\n link?: string;\n snippet?: string;\n date?: string;\n};\n\ntype MiniMaxRelatedSearch = {\n query?: string;\n};\n\ntype MiniMaxSearchResponse = {\n organic?: MiniMaxSearchResult[];\n related_searches?: MiniMaxRelatedSearch[];\n base_resp?: {\n status_code?: number;\n status_msg?: string;\n };\n};\n\nfunction resolveMiniMaxApiKey(searchConfig?: SearchConfigRecord): string | undefined {\n return (\n readConfiguredSecretString(searchConfig?.apiKey, \"tools.web.search.apiKey\") ??\n readProviderEnvValue([...MINIMAX_CODING_PLAN_ENV_VARS, \"MINIMAX_API_KEY\"])\n );\n}\n\nfunction isMiniMaxCnHost(value: string | undefined): boolean {\n const trimmed = value?.trim();\n if (!trimmed) {\n return false;\n }\n try {\n return new URL(trimmed).hostname.endsWith(\"minimaxi.com\");\n } catch {\n return trimmed.includes(\"minimaxi.com\");\n }\n}\n\nfunction resolveMiniMaxRegion(\n searchConfig?: SearchConfigRecord,\n config?: Record<string, unknown>,\n): \"cn\" | \"global\" {\n // 1. Explicit region in search config takes priority\n const minimax =\n typeof searchConfig?.minimax === \"object\" &&\n searchConfig.minimax !== null &&\n !Array.isArray(searchConfig.minimax)\n ? (searchConfig.minimax as Record<string, unknown>)\n : undefined;\n if (typeof minimax?.region === \"string\" && minimax.region.trim()) {\n return minimax.region === \"cn\" ? \"cn\" : \"global\";\n }\n\n // 2. Infer from the shared MiniMax host override.\n if (isMiniMaxCnHost(process.env.MINIMAX_API_HOST)) {\n return \"cn\";\n }\n\n // 3. Infer from model provider base URL (set by CN onboarding)\n const models = config?.models as Record<string, unknown> | undefined;\n const providers = models?.providers as Record<string, unknown> | undefined;\n const minimaxProvider = providers?.minimax as Record<string, unknown> | undefined;\n const portalProvider = providers?.[\"minimax-portal\"] as Record<string, unknown> | undefined;\n const baseUrl = typeof minimaxProvider?.baseUrl === \"string\" ? minimaxProvider.baseUrl : \"\";\n const portalBaseUrl = typeof portalProvider?.baseUrl === \"string\" ? portalProvider.baseUrl : \"\";\n if (isMiniMaxCnHost(baseUrl) || isMiniMaxCnHost(portalBaseUrl)) {\n return \"cn\";\n }\n\n return \"global\";\n}\n\nfunction resolveMiniMaxEndpoint(\n searchConfig?: SearchConfigRecord,\n config?: Record<string, unknown>,\n): string {\n return resolveMiniMaxRegion(searchConfig, config) === \"cn\"\n ? MINIMAX_SEARCH_ENDPOINT_CN\n : MINIMAX_SEARCH_ENDPOINT_GLOBAL;\n}\n\nasync function runMiniMaxSearch(params: {\n query: string;\n count: number;\n apiKey: string;\n endpoint: string;\n timeoutSeconds: number;\n}): Promise<{\n results: Array<Record<string, unknown>>;\n relatedSearches?: string[];\n}> {\n return withTrustedWebSearchEndpoint(\n {\n url: params.endpoint,\n timeoutSeconds: params.timeoutSeconds,\n init: {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${params.apiKey}`,\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n },\n body: JSON.stringify({ q: params.query }),\n },\n },\n async (res) => {\n if (!res.ok) {\n const detail = await res.text();\n throw new Error(`MiniMax Search API error (${res.status}): ${detail || res.statusText}`);\n }\n\n const data = (await res.json()) as MiniMaxSearchResponse;\n\n if (data.base_resp?.status_code && data.base_resp.status_code !== 0) {\n throw new Error(\n `MiniMax Search API error (${data.base_resp.status_code}): ${data.base_resp.status_msg || \"unknown error\"}`,\n );\n }\n\n const organic = Array.isArray(data.organic) ? data.organic : [];\n const results = organic.slice(0, params.count).map((entry) => {\n const title = entry.title ?? \"\";\n const url = entry.link ?? \"\";\n const snippet = entry.snippet ?? \"\";\n return {\n title: title ? wrapWebContent(title, \"web_search\") : \"\",\n url,\n description: snippet ? wrapWebContent(snippet, \"web_search\") : \"\",\n published: entry.date || undefined,\n siteName: resolveSiteName(url) || undefined,\n };\n });\n\n const relatedSearches = Array.isArray(data.related_searches)\n ? data.related_searches\n .map((r) => r.query)\n .filter((q): q is string => typeof q === \"string\" && q.length > 0)\n .map((q) => wrapWebContent(q, \"web_search\"))\n : undefined;\n\n return { results, relatedSearches };\n },\n );\n}\n\nconst MiniMaxSearchSchema = Type.Object({\n query: Type.String({ description: \"Search query string.\" }),\n count: Type.Optional(\n Type.Number({\n description: \"Number of results to return (1-10).\",\n minimum: 1,\n maximum: MAX_SEARCH_COUNT,\n }),\n ),\n});\n\nfunction missingMiniMaxKeyPayload() {\n return {\n error: \"missing_minimax_api_key\",\n message: `web_search (minimax) needs a MiniMax Coding Plan key. Run \\`${formatCliCommand(\"openclaw configure --section web\")}\\` to store it, or set MINIMAX_CODE_PLAN_KEY, MINIMAX_CODING_API_KEY, or MINIMAX_API_KEY in the Gateway environment.`,\n docs: \"https://docs.openclaw.ai/tools/web\",\n };\n}\n\nfunction createMiniMaxToolDefinition(\n searchConfig?: SearchConfigRecord,\n config?: Record<string, unknown>,\n): WebSearchProviderToolDefinition {\n return {\n description:\n \"Search the web using MiniMax Search API. Returns titles, URLs, snippets, and related search suggestions.\",\n parameters: MiniMaxSearchSchema,\n execute: async (args) => {\n const apiKey = resolveMiniMaxApiKey(searchConfig);\n if (!apiKey) {\n return missingMiniMaxKeyPayload();\n }\n\n const params = args as Record<string, unknown>;\n const query = readStringParam(params, \"query\", { required: true });\n const count =\n readNumberParam(params, \"count\", { integer: true }) ??\n searchConfig?.maxResults ??\n undefined;\n\n const resolvedCount = resolveSearchCount(count, DEFAULT_SEARCH_COUNT);\n const endpoint = resolveMiniMaxEndpoint(searchConfig, config);\n\n const cacheKey = buildSearchCacheKey([\"minimax\", endpoint, query, resolvedCount]);\n const cached = readCachedSearchPayload(cacheKey);\n if (cached) {\n return cached;\n }\n\n const start = Date.now();\n const timeoutSeconds = resolveSearchTimeoutSeconds(searchConfig);\n const cacheTtlMs = resolveSearchCacheTtlMs(searchConfig);\n\n const { results, relatedSearches } = await runMiniMaxSearch({\n query,\n count: resolvedCount,\n apiKey,\n endpoint,\n timeoutSeconds,\n });\n\n const payload: Record<string, unknown> = {\n query,\n provider: \"minimax\",\n count: results.length,\n tookMs: Date.now() - start,\n externalContent: {\n untrusted: true,\n source: \"web_search\",\n provider: \"minimax\",\n wrapped: true,\n },\n results,\n };\n\n if (relatedSearches && relatedSearches.length > 0) {\n payload.relatedSearches = relatedSearches;\n }\n\n writeCachedSearchPayload(cacheKey, payload, cacheTtlMs);\n return payload;\n },\n };\n}\n\nexport const __testing = {\n MINIMAX_SEARCH_ENDPOINT_GLOBAL,\n MINIMAX_SEARCH_ENDPOINT_CN,\n resolveMiniMaxApiKey,\n resolveMiniMaxEndpoint,\n resolveMiniMaxRegion,\n} as const;\n\nexport function createMiniMaxWebSearchProvider(): WebSearchProviderPlugin {\n return {\n id: \"minimax\",\n label: \"MiniMax Search\",\n hint: \"Structured results via MiniMax Coding Plan search API\",\n credentialLabel: \"MiniMax Coding Plan key\",\n envVars: [...MINIMAX_CODING_PLAN_ENV_VARS],\n placeholder: \"sk-cp-...\",\n signupUrl: \"https://platform.minimax.io/user-center/basic-information/interface-key\",\n docsUrl: \"https://docs.openclaw.ai/tools/minimax-search\",\n autoDetectOrder: 15,\n credentialPath: \"plugins.entries.minimax.config.webSearch.apiKey\",\n inactiveSecretPaths: [\"plugins.entries.minimax.config.webSearch.apiKey\"],\n getCredentialValue: (searchConfig) => searchConfig?.apiKey,\n setCredentialValue: setTopLevelCredentialValue,\n getConfiguredCredentialValue: (config) =>\n resolveProviderWebSearchPluginConfig(config, \"minimax\")?.apiKey,\n setConfiguredCredentialValue: (configTarget, value) => {\n setProviderWebSearchPluginConfigValue(configTarget, \"minimax\", \"apiKey\", value);\n },\n createTool: (ctx) =>\n createMiniMaxToolDefinition(\n mergeScopedSearchConfig(\n ctx.searchConfig as SearchConfigRecord | undefined,\n \"minimax\",\n resolveProviderWebSearchPluginConfig(ctx.config, \"minimax\"),\n { mirrorApiKeyToTopLevel: true },\n ) as SearchConfigRecord | undefined,\n ctx.config as Record<string, unknown> | undefined,\n ),\n };\n}\n"}}, "openclaw/extensions/minimax/index.ts": {"425bd114a1b8efa3b2330bc3e0fa1fe346362b13": {"t": 1785674022.1780307, "n": 11749, "h": "54236d366695a187", "c": "import {\n definePluginEntry,\n type ProviderAuthContext,\n type ProviderAuthResult,\n type ProviderCatalogContext,\n} from \"openclaw/plugin-sdk/plugin-entry\";\nimport {\n MINIMAX_OAUTH_MARKER,\n ensureAuthProfileStore,\n listProfilesForProvider,\n} from \"openclaw/plugin-sdk/provider-auth\";\nimport { buildOauthProviderAuthResult } from \"openclaw/plugin-sdk/provider-auth\";\nimport { createProviderApiKeyAuthMethod } from \"openclaw/plugin-sdk/provider-auth-api-key\";\nimport { buildProviderReplayFamilyHooks } from \"openclaw/plugin-sdk/provider-model-shared\";\nimport { buildProviderStreamFamilyHooks } from \"openclaw/plugin-sdk/provider-stream\";\nimport { fetchMinimaxUsage } from \"openclaw/plugin-sdk/provider-usage\";\nimport { isMiniMaxModernModelId, MINIMAX_DEFAULT_MODEL_ID } from \"./api.js\";\nimport {\n buildMinimaxImageGenerationProvider,\n buildMinimaxPortalImageGenerationProvider,\n} from \"./image-generation-provider.js\";\nimport {\n minimaxMediaUnderstandingProvider,\n minimaxPortalMediaUnderstandingProvider,\n} from \"./media-understanding-provider.js\";\nimport type { MiniMaxRegion } from \"./oauth.js\";\nimport { applyMinimaxApiConfig, applyMinimaxApiConfigCn } from \"./onboard.js\";\nimport { buildMinimaxPortalProvider, buildMinimaxProvider } from \"./provider-catalog.js\";\nimport { buildMinimaxSpeechProvider } from \"./speech-provider.js\";\nimport { createMiniMaxWebSearchProvider } from \"./src/minimax-web-search-provider.js\";\n\nconst API_PROVIDER_ID = \"minimax\";\nconst PORTAL_PROVIDER_ID = \"minimax-portal\";\nconst PROVIDER_LABEL = \"MiniMax\";\nconst DEFAULT_MODEL = MINIMAX_DEFAULT_MODEL_ID;\nconst DEFAULT_BASE_URL_CN = \"https://api.minimaxi.com/anthropic\";\nconst DEFAULT_BASE_URL_GLOBAL = \"https://api.minimax.io/anthropic\";\nconst MINIMAX_USAGE_ENV_VAR_KEYS = [\n \"MINIMAX_OAUTH_TOKEN\",\n \"MINIMAX_CODE_PLAN_KEY\",\n \"MINIMAX_CODING_API_KEY\",\n \"MINIMAX_API_KEY\",\n] as const;\nconst HYBRID_ANTHROPIC_OPENAI_REPLAY_HOOKS = buildProviderReplayFamilyHooks({\n family: \"hybrid-anthropic-openai\",\n anthropicModelDropThinkingBlocks: true,\n});\nconst MINIMAX_FAST_MODE_STREAM_HOOKS = buildProviderStreamFamilyHooks(\"minimax-fast-mode\");\n\nfunction resolveMinimaxReasoningOutputMode(): \"native\" {\n // Keep MiniMax on native reasoning mode. Tagged enforcement previously\n // suppressed normal assistant replies on this Anthropic-compatible surface.\n return \"native\";\n}\n\nfunction getDefaultBaseUrl(region: MiniMaxRegion): string {\n return region === \"cn\" ? DEFAULT_BASE_URL_CN : DEFAULT_BASE_URL_GLOBAL;\n}\n\nfunction apiModelRef(modelId: string): string {\n return `${API_PROVIDER_ID}/${modelId}`;\n}\n\nfunction portalModelRef(modelId: string): string {\n return `${PORTAL_PROVIDER_ID}/${modelId}`;\n}\n\nfunction buildPortalProviderCatalog(params: { baseUrl: string; apiKey: string }) {\n return {\n ...buildMinimaxPortalProvider(),\n baseUrl: params.baseUrl,\n apiKey: params.apiKey,\n };\n}\n\nfunction resolveApiCatalog(ctx: ProviderCatalogContext) {\n const apiKey = ctx.resolveProviderApiKey(API_PROVIDER_ID).apiKey;\n if (!apiKey) {\n return null;\n }\n return {\n provider: {\n ...buildMinimaxProvider(),\n apiKey,\n },\n };\n}\n\nfunction resolvePortalCatalog(ctx: ProviderCatalogContext) {\n const explicitProvider = ctx.config.models?.providers?.[PORTAL_PROVIDER_ID];\n const envApiKey = ctx.resolveProviderApiKey(PORTAL_PROVIDER_ID).apiKey;\n const authStore = ensureAuthProfileStore(ctx.agentDir, {\n allowKeychainPrompt: false,\n });\n const hasProfiles = listProfilesForProvider(authStore, PORTAL_PROVIDER_ID).length > 0;\n const explicitApiKey =\n typeof explicitProvider?.apiKey === \"string\" ? explicitProvider.apiKey.trim() : undefined;\n const apiKey = envApiKey ?? explicitApiKey ?? (hasProfiles ? MINIMAX_OAUTH_MARKER : undefined);\n if (!apiKey) {\n return null;\n }\n\n const explicitBaseUrl =\n typeof explicitProvider?.baseUrl === \"string\" ? explicitProvider.baseUrl.trim() : undefined;\n\n return {\n provider: buildPortalProviderCatalog({\n baseUrl: explicitBaseUrl || buildMinimaxPortalProvider().baseUrl,\n apiKey,\n }),\n };\n}\n\nfunction createOAuthHandler(region: MiniMaxRegion) {\n const defaultBaseUrl = getDefaultBaseUrl(region);\n const regionLabel = region === \"cn\" ? \"CN\" : \"Global\";\n\n return async (ctx: ProviderAuthContext): Promise<ProviderAuthResult> => {\n const progress = ctx.prompter.progress(`Starting MiniMax OAuth (${regionLabel})…`);\n try {\n const { loginMiniMaxPortalOAuth } = await import(\"./oauth.runtime.js\");\n const result = await loginMiniMaxPortalOAuth({\n openUrl: ctx.openUrl,\n note: ctx.prompter.note,\n progress,\n region,\n });\n\n progress.stop(\"MiniMax OAuth complete\");\n\n if (result.notification_message) {\n await ctx.prompter.note(result.notification_message, \"MiniMax OAuth\");\n }\n\n const baseUrl = result.resourceUrl || defaultBaseUrl;\n\n return buildOauthProviderAuthResult({\n providerId: PORTAL_PROVIDER_ID,\n defaultModel: portalModelRef(DEFAULT_MODEL),\n access: result.access,\n refresh: result.refresh,\n expires: result.expires,\n configPatch: {\n models: {\n providers: {\n [PORTAL_PROVIDER_ID]: {\n baseUrl,\n models: [],\n },\n },\n },\n agents: {\n defaults: {\n models: {\n [portalModelRef(\"MiniMax-M2.7\")]: { alias: \"minimax-m2.7\" },\n [portalModelRef(\"MiniMax-M2.7-highspeed\")]: {\n alias: \"minimax-m2.7-highspeed\",\n },\n },\n },\n },\n },\n notes: [\n \"MiniMax OAuth tokens auto-refresh. Re-run login if refresh fails or access is revoked.\",\n `Base URL defaults to ${defaultBaseUrl}. Override models.providers.${PORTAL_PROVIDER_ID}.baseUrl if needed.`,\n ...(result.notification_message ? [result.notification_message] : []),\n ],\n });\n } catch (err) {\n const errorMsg = err instanceof Error ? err.message : String(err);\n progress.stop(`MiniMax OAuth failed: ${errorMsg}`);\n await ctx.prompter.note(\n \"If OAuth fails, verify your MiniMax account has portal access and try again.\",\n \"MiniMax OAuth\",\n );\n throw err;\n }\n };\n}\n\nexport default definePluginEntry({\n id: API_PROVIDER_ID,\n name: \"MiniMax\",\n description: \"Bundled MiniMax API-key and OAuth provider plugin\",\n register(api) {\n api.registerProvider({\n id: API_PROVIDER_ID,\n label: PROVIDER_LABEL,\n hookAliases: [\"minimax-cn\"],\n docsPath: \"/providers/minimax\",\n envVars: [\"MINIMAX_API_KEY\"],\n auth: [\n createProviderApiKeyAuthMethod({\n providerId: API_PROVIDER_ID,\n methodId: \"api-global\",\n label: \"MiniMax API key (Global)\",\n hint: \"Global endpoint - api.minimax.io\",\n optionKey: \"minimaxApiKey\",\n flagName: \"--minimax-api-key\",\n envVar: \"MINIMAX_API_KEY\",\n promptMessage:\n \"Enter MiniMax API key (sk-api- or sk-cp-)\\nhttps://platform.minimax.io/user-center/basic-information/interface-key\",\n profileId: \"minimax:global\",\n allowProfile: false,\n defaultModel: apiModelRef(DEFAULT_MODEL),\n expectedProviders: [\"minimax\"],\n applyConfig: (cfg) => applyMinimaxApiConfig(cfg),\n wizard: {\n choiceId: \"minimax-global-api\",\n choiceLabel: \"MiniMax API key (Global)\",\n choiceHint: \"Global endpoint - api.minimax.io\",\n groupId: \"minimax\",\n groupLabel: \"MiniMax\",\n groupHint: \"M2.7 (recommended)\",\n },\n }),\n createProviderApiKeyAuthMethod({\n providerId: API_PROVIDER_ID,\n methodId: \"api-cn\",\n label: \"MiniMax API key (CN)\",\n hint: \"CN endpoint - api.minimaxi.com\",\n optionKey: \"minimaxApiKey\",\n flagName: \"--minimax-api-key\",\n envVar: \"MINIMAX_API_KEY\",\n promptMessage:\n \"Enter MiniMax CN API key (sk-api- or sk-cp-)\\nhttps://platform.minimaxi.com/user-center/basic-information/interface-key\",\n profileId: \"minimax:cn\",\n allowProfile: false,\n defaultModel: apiModelRef(DEFAULT_MODEL),\n expectedProviders: [\"minimax\", \"minimax-cn\"],\n applyConfig: (cfg) => applyMinimaxApiConfigCn(cfg),\n wizard: {\n choiceId: \"minimax-cn-api\",\n choiceLabel: \"MiniMax API key (CN)\",\n choiceHint: \"CN endpoint - api.minimaxi.com\",\n groupId: \"minimax\",\n groupLabel: \"MiniMax\",\n groupHint: \"M2.7 (recommended)\",\n },\n }),\n ],\n catalog: {\n order: \"simple\",\n run: async (ctx) => resolveApiCatalog(ctx),\n },\n resolveUsageAuth: async (ctx) => {\n const portalOauth = await ctx.resolveOAuthToken({ provider: PORTAL_PROVIDER_ID });\n if (portalOauth) {\n return portalOauth;\n }\n const apiKey = ctx.resolveApiKeyFromConfigAndStore({\n providerIds: [API_PROVIDER_ID, PORTAL_PROVIDER_ID],\n envDirect: MINIMAX_USAGE_ENV_VAR_KEYS.map((name) => ctx.env[name]),\n });\n return apiKey ? { token: apiKey } : null;\n },\n ...HYBRID_ANTHROPIC_OPENAI_REPLAY_HOOKS,\n ...MINIMAX_FAST_MODE_STREAM_HOOKS,\n resolveReasoningOutputMode: () => resolveMinimaxReasoningOutputMode(),\n isModernModelRef: ({ modelId }) => isMiniMaxModernModelId(modelId),\n fetchUsageSnapshot: async (ctx) =>\n await fetchMinimaxUsage(ctx.token, ctx.timeoutMs, ctx.fetchFn),\n });\n\n api.registerMediaUnderstandingProvider(minimaxMediaUnderstandingProvider);\n api.registerMediaUnderstandingProvider(minimaxPortalMediaUnderstandingProvider);\n\n api.registerProvider({\n id: PORTAL_PROVIDER_ID,\n label: PROVIDER_LABEL,\n hookAliases: [\"minimax-portal-cn\"],\n docsPath: \"/providers/minimax\",\n envVars: [\"MINIMAX_OAUTH_TOKEN\", \"MINIMAX_API_KEY\"],\n catalog: {\n run: async (ctx) => resolvePortalCatalog(ctx),\n },\n auth: [\n {\n id: \"oauth\",\n label: \"MiniMax OAuth (Global)\",\n hint: \"Global endpoint - api.minimax.io\",\n kind: \"device_code\",\n wizard: {\n choiceId: \"minimax-global-oauth\",\n choiceLabel: \"MiniMax OAuth (Global)\",\n choiceHint: \"Global endpoint - api.minimax.io\",\n groupId: \"minimax\",\n groupLabel: \"MiniMax\",\n groupHint: \"M2.7 (recommended)\",\n },\n run: createOAuthHandler(\"global\"),\n },\n {\n id: \"oauth-cn\",\n label: \"MiniMax OAuth (CN)\",\n hint: \"CN endpoint - api.minimaxi.com\",\n kind: \"device_code\",\n wizard: {\n choiceId: \"minimax-cn-oauth\",\n choiceLabel: \"MiniMax OAuth (CN)\",\n choiceHint: \"CN endpoint - api.minimaxi.com\",\n groupId: \"minimax\",\n groupLabel: \"MiniMax\",\n groupHint: \"M2.7 (recommended)\",\n },\n run: createOAuthHandler(\"cn\"),\n },\n ],\n ...HYBRID_ANTHROPIC_OPENAI_REPLAY_HOOKS,\n ...MINIMAX_FAST_MODE_STREAM_HOOKS,\n resolveReasoningOutputMode: () => resolveMinimaxReasoningOutputMode(),\n isModernModelRef: ({ modelId }) => isMiniMaxModernModelId(modelId),\n });\n api.registerImageGenerationProvider(buildMinimaxImageGenerationProvider());\n api.registerImageGenerationProvider(buildMinimaxPortalImageGenerationProvider());\n api.registerSpeechProvider(buildMinimaxSpeechProvider());\n api.registerWebSearchProvider(createMiniMaxWebSearchProvider());\n },\n});\n"}}}} |