diff --git a/gitnexus-web/src/components/SettingsPanel.tsx b/gitnexus-web/src/components/SettingsPanel.tsx
index ab823d240..d60475107 100644
--- a/gitnexus-web/src/components/SettingsPanel.tsx
+++ b/gitnexus-web/src/components/SettingsPanel.tsx
@@ -281,7 +281,7 @@ export const SettingsPanel = ({ isOpen, onClose, onSettingsSaved, backendUrl, is
if (!isOpen) return null;
- const providers: LLMProvider[] = ['openai', 'gemini', 'anthropic', 'azure-openai', 'ollama', 'openrouter'];
+ const providers: LLMProvider[] = ['openai', 'gemini', 'anthropic', 'azure-openai', 'ollama', 'openrouter', 'minimax'];
return (
@@ -366,7 +366,7 @@ export const SettingsPanel = ({ isOpen, onClose, onSettingsSaved, backendUrl, is
w-8 h-8 rounded-lg flex items-center justify-center text-lg
${settings.activeProvider === provider ? 'bg-accent/20' : 'bg-surface'}
`}>
- {provider === 'openai' ? '🤖' : provider === 'gemini' ? '💎' : provider === 'anthropic' ? '🧠' : provider === 'ollama' ? '🦙' : provider === 'openrouter' ? '🌐' : '☁️'}
+ {provider === 'openai' ? '🤖' : provider === 'gemini' ? '💎' : provider === 'anthropic' ? '🧠' : provider === 'ollama' ? '🦙' : provider === 'openrouter' ? '🌐' : provider === 'minimax' ? '⚡' : '☁️'}
{getProviderDisplayName(provider)}
@@ -814,7 +814,64 @@ export const SettingsPanel = ({ isOpen, onClose, onSettingsSaved, backendUrl, is
)}
+ {/* MiniMax Settings */}
+ {settings.activeProvider === 'minimax' && (
+
+
+
+
+ setSettings(prev => ({
+ ...prev,
+ minimax: { ...prev.minimax!, apiKey: e.target.value }
+ }))}
+ placeholder="Enter your MiniMax API key"
+ className="w-full px-4 py-3 pr-12 bg-elevated border border-border-subtle rounded-xl text-text-primary placeholder:text-text-muted focus:border-accent focus:ring-2 focus:ring-accent/20 outline-none transition-all"
+ />
+
+
+
+ Get your API key from{' '}
+
+ MiniMax Platform
+
+
+
+
+
+
setSettings(prev => ({
+ ...prev,
+ minimax: { ...prev.minimax!, model: e.target.value }
+ }))}
+ placeholder="e.g., MiniMax-M2.5, MiniMax-M2.5-highspeed"
+ className="w-full px-4 py-3 bg-elevated border border-border-subtle rounded-xl text-text-primary placeholder:text-text-muted focus:border-accent focus:ring-2 focus:ring-accent/20 outline-none transition-all font-mono text-sm"
+ />
+
+ Available models: MiniMax-M2.5 (default), MiniMax-M2.5-highspeed (faster)
+
+
+
+ )}
{/* Privacy Note */}
diff --git a/gitnexus-web/src/core/llm/agent.ts b/gitnexus-web/src/core/llm/agent.ts
index 6649f5742..88e07d40f 100644
--- a/gitnexus-web/src/core/llm/agent.ts
+++ b/gitnexus-web/src/core/llm/agent.ts
@@ -13,14 +13,15 @@ import { ChatAnthropic } from '@langchain/anthropic';
import { ChatOllama } from '@langchain/ollama';
import type { BaseChatModel } from '@langchain/core/language_models/chat_models';
import { createGraphRAGTools } from './tools';
-import type {
- ProviderConfig,
+import type {
+ ProviderConfig,
OpenAIConfig,
- AzureOpenAIConfig,
+ AzureOpenAIConfig,
GeminiConfig,
AnthropicConfig,
OllamaConfig,
OpenRouterConfig,
+ MiniMaxConfig,
AgentStreamChunk,
} from './types';
import {
@@ -197,7 +198,7 @@ export const createChatModel = (config: ProviderConfig): BaseChatModel => {
case 'openrouter': {
const openRouterConfig = config as OpenRouterConfig;
-
+
// Debug logging
if (import.meta.env.DEV) {
console.log('🌐 OpenRouter config:', {
@@ -207,11 +208,11 @@ export const createChatModel = (config: ProviderConfig): BaseChatModel => {
baseUrl: openRouterConfig.baseUrl,
});
}
-
+
if (!openRouterConfig.apiKey || openRouterConfig.apiKey.trim() === '') {
throw new Error('OpenRouter API key is required but was not provided');
}
-
+
return new ChatOpenAI({
openAIApiKey: openRouterConfig.apiKey,
apiKey: openRouterConfig.apiKey, // Fallback for some versions
@@ -225,7 +226,26 @@ export const createChatModel = (config: ProviderConfig): BaseChatModel => {
streaming: true,
});
}
-
+
+ case 'minimax': {
+ const minimaxConfig = config as MiniMaxConfig;
+
+ if (!minimaxConfig.apiKey || minimaxConfig.apiKey.trim() === '') {
+ throw new Error('MiniMax API key is required but was not provided');
+ }
+
+ return new ChatAnthropic({
+ anthropicApiKey: minimaxConfig.apiKey,
+ model: minimaxConfig.model,
+ temperature: minimaxConfig.temperature ?? 0.1,
+ maxTokens: minimaxConfig.maxTokens ?? 8192,
+ streaming: true,
+ clientOptions: {
+ baseURL: 'https://api.minimax.io/anthropic',
+ },
+ });
+ }
+
default:
throw new Error(`Unsupported provider: ${(config as any).provider}`);
}
diff --git a/gitnexus-web/src/core/llm/settings-service.ts b/gitnexus-web/src/core/llm/settings-service.ts
index 0c35b9623..f4ef5993a 100644
--- a/gitnexus-web/src/core/llm/settings-service.ts
+++ b/gitnexus-web/src/core/llm/settings-service.ts
@@ -5,9 +5,9 @@
* All API keys are stored locally - never sent to any server except the LLM provider.
*/
-import {
- LLMSettings,
- DEFAULT_LLM_SETTINGS,
+import {
+ LLMSettings,
+ DEFAULT_LLM_SETTINGS,
LLMProvider,
OpenAIConfig,
AzureOpenAIConfig,
@@ -15,6 +15,7 @@ import {
AnthropicConfig,
OllamaConfig,
OpenRouterConfig,
+ MiniMaxConfig,
ProviderConfig,
} from './types';
@@ -60,6 +61,10 @@ export const loadSettings = (): LLMSettings => {
...DEFAULT_LLM_SETTINGS.openrouter,
...parsed.openrouter,
},
+ minimax: {
+ ...DEFAULT_LLM_SETTINGS.minimax,
+ ...parsed.minimax,
+ },
};
} catch (error) {
console.warn('Failed to load LLM settings:', error);
@@ -89,6 +94,7 @@ export const updateProviderSettings = (
T extends 'gemini' ? Partial> :
T extends 'anthropic' ? Partial> :
T extends 'ollama' ? Partial> :
+ T extends 'minimax' ? Partial> :
never
>
): LLMSettings => {
@@ -162,6 +168,17 @@ export const updateProviderSettings = (
saveSettings(updated);
return updated;
}
+ case 'minimax': {
+ const updated: LLMSettings = {
+ ...current,
+ minimax: {
+ ...(current.minimax ?? {}),
+ ...(updates as Partial>),
+ },
+ };
+ saveSettings(updated);
+ return updated;
+ }
default: {
// Should be unreachable due to T extends LLMProvider, but keep a safe fallback
const updated: LLMSettings = { ...current };
@@ -245,7 +262,16 @@ export const getActiveProviderConfig = (): ProviderConfig | null => {
temperature: settings.openrouter.temperature,
maxTokens: settings.openrouter.maxTokens,
} as OpenRouterConfig;
-
+
+ case 'minimax':
+ if (!settings.minimax?.apiKey) {
+ return null;
+ }
+ return {
+ provider: 'minimax',
+ ...settings.minimax,
+ } as MiniMaxConfig;
+
default:
return null;
}
@@ -282,6 +308,8 @@ export const getProviderDisplayName = (provider: LLMProvider): string => {
return 'Ollama (Local)';
case 'openrouter':
return 'OpenRouter';
+ case 'minimax':
+ return 'MiniMax';
default:
return provider;
}
@@ -303,6 +331,8 @@ export const getAvailableModels = (provider: LLMProvider): string[] => {
return ['claude-sonnet-4-20250514', 'claude-3-5-sonnet-20241022', 'claude-3-5-haiku-20241022', 'claude-3-opus-20240229'];
case 'ollama':
return ['llama3.2', 'llama3.1', 'mistral', 'codellama', 'deepseek-coder'];
+ case 'minimax':
+ return ['MiniMax-M2.5', 'MiniMax-M2.5-highspeed'];
default:
return [];
}
diff --git a/gitnexus-web/src/core/llm/types.ts b/gitnexus-web/src/core/llm/types.ts
index 8e43673fa..d2597ec18 100644
--- a/gitnexus-web/src/core/llm/types.ts
+++ b/gitnexus-web/src/core/llm/types.ts
@@ -8,7 +8,7 @@
/**
* Supported LLM providers
*/
-export type LLMProvider = 'openai' | 'azure-openai' | 'gemini' | 'anthropic' | 'ollama' | 'openrouter';
+export type LLMProvider = 'openai' | 'azure-openai' | 'gemini' | 'anthropic' | 'ollama' | 'openrouter' | 'minimax';
/**
* Base configuration shared by all providers
@@ -78,10 +78,19 @@ export interface OpenRouterConfig extends BaseProviderConfig {
baseUrl?: string; // defaults to https://openrouter.ai/api/v1
}
+/**
+ * MiniMax configuration (Anthropic-compatible API)
+ */
+export interface MiniMaxConfig extends BaseProviderConfig {
+ provider: 'minimax';
+ apiKey: string;
+ model: string; // e.g., 'MiniMax-M2.5', 'MiniMax-M2.5-highspeed'
+}
+
/**
* Union type for all provider configurations
*/
-export type ProviderConfig = OpenAIConfig | AzureOpenAIConfig | GeminiConfig | AnthropicConfig | OllamaConfig | OpenRouterConfig;
+export type ProviderConfig = OpenAIConfig | AzureOpenAIConfig | GeminiConfig | AnthropicConfig | OllamaConfig | OpenRouterConfig | MiniMaxConfig;
/**
* Stored settings (what goes to localStorage)
@@ -98,6 +107,7 @@ export interface LLMSettings {
anthropic?: Partial>;
ollama?: Partial>;
openrouter?: Partial>;
+ minimax?: Partial>;
// Intelligent Clustering Settings
intelligentClustering: boolean;
@@ -148,6 +158,11 @@ export const DEFAULT_LLM_SETTINGS: LLMSettings = {
baseUrl: 'https://openrouter.ai/api/v1',
temperature: 0.1,
},
+ minimax: {
+ apiKey: '',
+ model: 'MiniMax-M2.5',
+ temperature: 0.1,
+ },
};
/**